Skip to content

Commit baf084c

Browse files
chat page design changes and some extra features on settings page. also made some widgets modular
1 parent f9c4a29 commit baf084c

8 files changed

Lines changed: 570 additions & 84 deletions

File tree

mobile/lib/main.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ class MyApp extends StatelessWidget {
2828
scrolledUnderElevation: 0,
2929
elevation: 0,
3030
),
31-
scaffoldBackgroundColor: const Color.fromARGB(255, 196, 195, 200),
31+
scaffoldBackgroundColor: const Color.fromARGB(255, 192, 195, 205),
3232
colorScheme: ColorScheme.fromSeed(
3333
seedColor: Colors.blue,
3434
primary: Colors.blue[700],

mobile/lib/pages/chat_page.dart

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import 'package:flutter/material.dart';
2+
import 'package:mob/widgets/chat_screen_modular_widgets.dart';
3+
4+
class ChatPage extends StatefulWidget {
5+
const ChatPage({super.key});
6+
7+
@override
8+
State<ChatPage> createState() => _ChatPageState();
9+
}
10+
11+
class _ChatPageState extends State<ChatPage> {
12+
// this class is only for message data
13+
final List<Map<String, dynamic>> messages = [
14+
{"text": "Hey! How's the app coming along?", "isMe": false},
15+
{"text": "Going great! Just building the UI now.", "isMe": true},
16+
{"text": "Love the glass morphic effect on the app bar!", "isMe": false},
17+
18+
{"text": "Hey! How's the app coming along?", "isMe": false},
19+
{"text": "Going great! Just building the UI now.", "isMe": true},
20+
{"text": "Love the glass morphic effect on the app bar!", "isMe": false},
21+
22+
{"text": "Hey! How's the app coming along?", "isMe": false},
23+
{"text": "Going great! Just building the UI now.", "isMe": true},
24+
{"text": "Love the glass morphic effect on the app bar!", "isMe": false},
25+
26+
{"text": "Hey! How's the app coming along?", "isMe": false},
27+
{"text": "Going great! Just building the UI now.", "isMe": true},
28+
{"text": "Love the glass morphic effect on the app bar!", "isMe": false},
29+
30+
{"text": "Hey! How's the app coming along?", "isMe": false},
31+
{"text": "Going great! Just building the UI now.", "isMe": true},
32+
{"text": "Love the glass morphic effect on the app bar!", "isMe": false},
33+
34+
{"text": "Hey! How's the app coming along?", "isMe": false},
35+
{"text": "Going great! Just building the UI now.", "isMe": true},
36+
{"text": "Love the glass morphic effect on the app bar!", "isMe": false},
37+
38+
{"text": "Hey! How's the app coming along?", "isMe": false},
39+
{"text": "Going great! Just building the UI now.", "isMe": true},
40+
{"text": "Love the glass morphic effect on the app bar!", "isMe": false},
41+
];
42+
43+
void _addNewMessage(String text) {
44+
setState(() {
45+
messages.add({"text": text, "isMe": true});
46+
});
47+
}
48+
49+
@override
50+
Widget build(BuildContext context) {
51+
return Scaffold(
52+
extendBody: true,
53+
extendBodyBehindAppBar: true,
54+
appBar: const GlassAppBar(name: 'Name', status: 'Activity Status'),
55+
body: ListView.builder(
56+
padding: const EdgeInsets.only(
57+
top: 120,
58+
bottom: 100,
59+
left: 16,
60+
right: 16,
61+
),
62+
itemCount: messages.length,
63+
itemBuilder: (context, index) {
64+
final msg = messages[index];
65+
return ChatBubble(message: msg['text'], isMe: msg['isMe']);
66+
},
67+
),
68+
// Using the modularized Input Area
69+
bottomNavigationBar: ChatInputArea(onSendMessage: _addNewMessage),
70+
);
71+
}
72+
}

mobile/lib/pages/home_page.dart

Lines changed: 68 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ class _HomePageState extends State<HomePage> {
5353
children: [
5454
Icon(
5555
isSelected ? activeIcon : icon,
56-
color: Colors.black87,
56+
color: isSelected ? Colors.blueAccent : Colors.black54,
5757
size: 24,
5858
),
5959
AnimatedSize(
@@ -63,10 +63,12 @@ class _HomePageState extends State<HomePage> {
6363
padding: const EdgeInsets.only(top: 2),
6464
child: Text(
6565
label,
66-
style: const TextStyle(
66+
style: TextStyle(
6767
fontSize: 12,
68-
fontWeight: FontWeight.w600,
69-
color: Colors.black87,
68+
fontWeight: isSelected
69+
? FontWeight.bold
70+
: FontWeight.w600,
71+
color: isSelected ? Colors.blueAccent : Colors.black54,
7072
),
7173
),
7274
),
@@ -78,47 +80,53 @@ class _HomePageState extends State<HomePage> {
7880
);
7981
}
8082

81-
Widget _buildGlassNavigationBar() {
83+
Widget buildGlassNavigationBar() {
8284
return SafeArea(
8385
child: Padding(
84-
padding: const EdgeInsets.only(left: 20, right: 20, bottom: 15),
86+
padding: const EdgeInsets.only(left: 20, right: 20, bottom: 20),
8587
child: ClipRRect(
86-
borderRadius: BorderRadius.circular(16),
88+
borderRadius: BorderRadius.circular(24),
8789
child: BackdropFilter(
88-
filter: ImageFilter.blur(sigmaX: 15, sigmaY: 15),
90+
// LOWERED BLUR: from 20 to 12
91+
filter: ImageFilter.blur(sigmaX: 12, sigmaY: 12),
8992
child: Container(
90-
height: 60,
91-
color: const Color.fromARGB(78, 255, 255, 255),
93+
height: 65,
94+
decoration: BoxDecoration(
95+
// LOWERED OPACITY: from 150 to 40
96+
color: const Color.fromARGB(40, 255, 255, 255),
97+
borderRadius: BorderRadius.circular(24),
98+
border: Border.all(
99+
// LOWERED BORDER OPACITY: from 0.6 to 0.3
100+
color: Colors.white.withValues(alpha: 0.3),
101+
width: 1.5,
102+
),
103+
),
92104
child: LayoutBuilder(
93105
builder: (context, constraints) {
94106
final tabWidth = constraints.maxWidth / 3;
95107

96108
return Stack(
97109
children: [
98110
AnimatedPositioned(
99-
duration: const Duration(milliseconds: 500),
100-
curve: Curves.decelerate,
111+
duration: const Duration(milliseconds: 400),
112+
curve: Curves.easeOutCubic,
101113
left: _page * tabWidth,
102114
top: 0,
103115
bottom: 0,
104116
width: tabWidth,
105117
child: Padding(
106-
padding: const EdgeInsets.all(6.0),
118+
padding: const EdgeInsets.all(8.0),
107119
child: Container(
108120
decoration: BoxDecoration(
109-
color: const Color.fromARGB(123, 255, 255, 255),
110-
borderRadius: BorderRadius.circular(15),
121+
// Using a highly transparent white for the active tab pill
122+
color: Colors.white.withValues(alpha: 0.8),
123+
borderRadius: BorderRadius.circular(16),
111124
boxShadow: [
112125
BoxShadow(
113-
color: const Color.fromARGB(
114-
255,
115-
0,
116-
0,
117-
0,
118-
).withValues(alpha: 0.08),
119-
blurRadius: 10,
120-
spreadRadius: 2,
121-
offset: const Offset(0, 0),
126+
color: Colors.black.withValues(alpha: 0.05),
127+
blurRadius: 8,
128+
spreadRadius: 1,
129+
offset: const Offset(0, 2),
122130
),
123131
],
124132
),
@@ -161,7 +169,7 @@ class _HomePageState extends State<HomePage> {
161169
);
162170
}
163171

164-
Widget _buildHomeTab() {
172+
Widget buildHomeTab() {
165173
return CustomScrollView(
166174
slivers: [
167175
SliverAppBar(
@@ -180,7 +188,7 @@ class _HomePageState extends State<HomePage> {
180188
),
181189
),
182190
actionsPadding: const EdgeInsets.symmetric(horizontal: 15),
183-
leading: const Icon(Icons.security),
191+
leading: const Icon(Icons.security, color: Colors.black87),
184192
title: AnimatedSwitcher(
185193
switchInCurve: Curves.decelerate,
186194
switchOutCurve: Curves.decelerate,
@@ -194,19 +202,34 @@ class _HomePageState extends State<HomePage> {
194202
return SlideTransition(position: offsetAnimation, child: child);
195203
},
196204
child: _isSearchOpen
197-
? TextField(
198-
controller: _searchController,
199-
key: const ValueKey('search'),
200-
decoration: InputDecoration(
201-
hintText: 'Search',
202-
border: OutlineInputBorder(borderSide: BorderSide.none),
205+
? SizedBox(
206+
height: 40,
207+
child: TextField(
208+
controller: _searchController,
209+
key: const ValueKey('search'),
210+
autofocus: true,
211+
decoration: InputDecoration(
212+
hintText: 'Search...',
213+
filled: true,
214+
// Kept search background subtle
215+
fillColor: Colors.black.withValues(alpha: 0.05),
216+
contentPadding: const EdgeInsets.symmetric(
217+
horizontal: 16,
218+
vertical: 0,
219+
),
220+
border: OutlineInputBorder(
221+
borderRadius: BorderRadius.circular(20),
222+
borderSide: BorderSide.none,
223+
),
224+
),
203225
),
204226
)
205227
: const Text(
206228
'Elephant',
207229
style: TextStyle(
208-
letterSpacing: 1,
209-
fontWeight: FontWeight.w400,
230+
letterSpacing: 1.2,
231+
fontWeight: FontWeight.w600,
232+
color: Colors.black87,
210233
),
211234
key: ValueKey('title'),
212235
),
@@ -216,17 +239,23 @@ class _HomePageState extends State<HomePage> {
216239
onPressed: () {
217240
setState(() {
218241
_isSearchOpen = !_isSearchOpen;
242+
if (!_isSearchOpen) _searchController.clear();
219243
});
220244
},
221-
icon: const Icon(Icons.search),
245+
icon: Icon(
246+
_isSearchOpen ? Icons.close : Icons.search,
247+
color: Colors.black87,
248+
),
222249
),
223250
],
224251
),
225252
SliverList.builder(
226253
itemCount: 20,
227-
itemBuilder: (context, index) => chatCard(),
254+
itemBuilder: (context, index) => chatCard(context),
255+
),
256+
SliverList(
257+
delegate: SliverChildListDelegate([const SizedBox(height: 120)]),
228258
),
229-
SliverList(delegate: SliverChildListDelegate([SizedBox(height: 100)])),
230259
],
231260
);
232261
}
@@ -236,17 +265,15 @@ class _HomePageState extends State<HomePage> {
236265
return Scaffold(
237266
extendBodyBehindAppBar: true,
238267
extendBody: true,
239-
240268
body: IndexedStack(
241269
index: _page,
242270
children: [
243-
_buildHomeTab(),
271+
buildHomeTab(),
244272
const Center(child: Text("Call Page Content")),
245273
SettingsPage(),
246274
],
247275
),
248-
249-
bottomNavigationBar: _buildGlassNavigationBar(),
276+
bottomNavigationBar: buildGlassNavigationBar(),
250277
);
251278
}
252279
}

mobile/lib/pages/settings_page.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,9 @@ class SettingsPage extends StatelessWidget {
2727
elevation: 0,
2828
backgroundColor: Colors.transparent,
2929
flexibleSpace: ClipRRect(
30+
clipBehavior: Clip.antiAlias,
3031
child: BackdropFilter(
32+
enabled: true,
3133
filter: ImageFilter.blur(sigmaX: 15, sigmaY: 15),
3234
child: Container(
3335
color: const Color.fromARGB(78, 255, 255, 255),

0 commit comments

Comments
 (0)