Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Performance Enhancements #2089

Open
wants to merge 35 commits into
base: experimental
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 33 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
f13f384
implemented cached network image
klortiz13 Sep 14, 2024
1087f7b
finished implementing imagecacheloading
klortiz13 Sep 20, 2024
ae9de03
fixed some small ui
klortiz13 Sep 20, 2024
93f76e2
cached the image of events, scanner, and myCHart
klortiz13 Sep 20, 2024
6ef2b92
Merge pull request #1 from parthshindee/kristhian-cached-image-packag…
parthshindee Sep 20, 2024
542be64
implemented ListView.builder in the media card. Also removed unused v…
klortiz13 Sep 21, 2024
e8dc7db
implemented listview builder in weather card
klortiz13 Sep 21, 2024
87bc706
implemented cachedNetworkImage to weather card
klortiz13 Sep 21, 2024
0fd24ca
implemented cache image to student id
klortiz13 Sep 21, 2024
e0314ae
implemented pageView.builder in shuttle card
klortiz13 Sep 21, 2024
0cbe57b
implemented pageVIew.builder in parking card
klortiz13 Sep 21, 2024
b763805
implemented cached image to notices card
klortiz13 Sep 21, 2024
8f25540
implemented listview builder to the news card and imageLoader to the …
klortiz13 Sep 22, 2024
0cfa9e2
fixed employee_id card and finals card
klortiz13 Sep 22, 2024
476b0d3
resized shuttle card
klortiz13 Sep 22, 2024
22f634f
implemented lazy loading in dinning card
klortiz13 Sep 22, 2024
d31b64f
fixed loading indicator in student id
klortiz13 Sep 22, 2024
81d6991
fixed loading indicator in wheather card
klortiz13 Sep 22, 2024
ad3e7f2
fixed media card
klortiz13 Sep 22, 2024
a9bdade
implemented listview builder in classes card
klortiz13 Sep 22, 2024
84647ec
implemented list view builder in availability display .dart
klortiz13 Sep 22, 2024
d88a86f
refactored availability detail view to implement listview builder
klortiz13 Sep 22, 2024
2ac5e20
implemented pageview builder in availability card
klortiz13 Sep 22, 2024
ee3e22d
Merge pull request #2 from parthshindee/kristhian-lazy-loading
klortiz13 Sep 22, 2024
6bee42b
converted student_id_card into a stateless widget card
klortiz13 Sep 22, 2024
aec972a
converted employee id to stateless
klortiz13 Sep 22, 2024
f69db57
fixed typo in student id card
klortiz13 Sep 22, 2024
cef26c6
Merge pull request #3 from parthshindee/kristhian-stateless-conversion
klortiz13 Sep 29, 2024
e59a1ad
merged with upstream
klortiz13 Sep 29, 2024
038a06e
updated
parthshindee Oct 14, 2024
b39a732
updated
parthshindee Oct 14, 2024
21ea0a4
Merge remote-tracking branch 'origin/experimental' into experimental
parthshindee Oct 14, 2024
144ea70
updated
parthshindee Nov 7, 2024
f52041a
updated pubspeck
parthshindee Dec 15, 2024
bf1657a
pulled from upstream
parthshindee Dec 15, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 21 additions & 18 deletions lib/ui/availability/availability_card.dart
Original file line number Diff line number Diff line change
Expand Up @@ -43,24 +43,24 @@ class _AvailabilityCardState extends State<AvailabilityCard> {
}

Widget buildAvailabilityCard(List<AvailabilityModel?> data) {
List<Widget> locationsList = [];
RegExp multiPager = RegExp(r' \(\d+/\d+\)$');
// loop through all the models, adding each one to locationsList
for (AvailabilityModel? model in data) {
if (model != null) {
String curName = model.name!;
RegExpMatch? match = multiPager.firstMatch(curName);
if (match != null) {
curName = curName.replaceRange(match.start, match.end, '');
}
if (_availabilityDataProvider.locationViewState[curName]!) {
locationsList.add(AvailabilityDisplay(model: model));
}
// RegExp multiPager = RegExp(r' \(\d+/\d+\)$');
// Filter the models and create a list of only the valid ones
List<Widget> locationsList = data
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't tell if this is proper usage of functional-style iterator methods. Let's try to rework this one.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@parthshindee let's meet on this one individually to see the best solution. Possible precedent case for the official Campus Mobile Style Guide

.where((model) {
if (model == null) return false;
String curName = model.name!;
RegExp multiPager = RegExp(r' \(\d+/\d+\)$');
RegExpMatch? match = multiPager.firstMatch(curName);
if (match != null) {
curName = curName.replaceRange(match.start, match.end, '');
}
}
return _availabilityDataProvider.locationViewState[curName]!;
})
.map((model) => AvailabilityDisplay(model: model!))
.toList();

// the user chose no location, so instead show "No Location to Display"
if (locationsList.length == 0) {
// If no location is available, show "No Location to Display"
if (locationsList.isEmpty) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
Expand All @@ -85,9 +85,12 @@ class _AvailabilityCardState extends State<AvailabilityCard> {
return Column(
children: <Widget>[
Flexible(
child: PageView(
child: PageView.builder(
controller: _controller,
children: locationsList,
itemCount: locationsList.length,
itemBuilder: (context, index) {
return locationsList[index];
},
),
),
SingleChildScrollView(
Expand Down
100 changes: 49 additions & 51 deletions lib/ui/availability/availability_detail_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,65 +15,63 @@ class AvailabilityDetailedView extends StatelessWidget {
}

Widget buildLocationsList(BuildContext context, subLocation) {
// Add a tile for the subLocation name
List<Widget> list = [];
list.add(ListTile(
title: Text(
"${subLocation.name}",
style: TextStyle(
color: Theme.of(context).colorScheme.secondary,
fontSize: 24,
fontWeight: FontWeight.bold),
),
));

// Add a tile for every floor in the subLocation list
for (int i = 0; i < subLocation.floors.length; i++) {
Floor floor = subLocation.floors[i];
list.add(
ListTile(
title: Text(
"${floor.name}",
style: TextStyle(
return ListView.builder(
physics: BouncingScrollPhysics(),
itemCount: subLocation.floors.length + 1, // +1 to include the subLocation name tile
itemBuilder: (context, index) {
if (index == 0) {
// Add the subLocation name as the first ListTile
return ListTile(
title: Text(
"${subLocation.name}",
style: TextStyle(
color: Theme.of(context).colorScheme.secondary,
fontSize: LOCATION_FONT_SIZE),
),
subtitle: Column(
children: <Widget>[
Align(
fontSize: 24,
fontWeight: FontWeight.bold,
),
),
);
} else {
// Add tiles for each floor in the subLocation
Floor floor = subLocation.floors[index - 1]; // Adjust index for floors
return ListTile(
title: Text(
"${floor.name}",
style: TextStyle(
color: Theme.of(context).colorScheme.secondary,
fontSize: LOCATION_FONT_SIZE,
),
),
subtitle: Column(
children: <Widget>[
Align(
alignment: Alignment.centerLeft,
child: Text(
(100 * percentAvailability(floor)).toInt().toString() +
'% Busy',
// style: TextStyle(color: Colors.black),
)),
Align(
alignment: Alignment.centerLeft,
child: SizedBox(
height: PROGRESS_BAR_HEIGHT,
width: PROGRESS_BAR_WIDTH,
child: ClipRRect(
borderRadius: BorderRadius.circular(BORDER_RADIUS),
child: LinearProgressIndicator(
value: percentAvailability(floor) as double?,
backgroundColor: Colors.grey[BACKGROUND_GREY_SHADE],
valueColor: AlwaysStoppedAnimation<Color>(
setIndicatorColor(
percentAvailability(floor),
(100 * percentAvailability(floor)).toInt().toString() + '% Busy',
),
),
Align(
alignment: Alignment.centerLeft,
child: SizedBox(
height: PROGRESS_BAR_HEIGHT,
width: PROGRESS_BAR_WIDTH,
child: ClipRRect(
borderRadius: BorderRadius.circular(BORDER_RADIUS),
child: LinearProgressIndicator(
value: percentAvailability(floor) as double?,
backgroundColor: Colors.grey[BACKGROUND_GREY_SHADE],
valueColor: AlwaysStoppedAnimation<Color>(
setIndicatorColor(percentAvailability(floor)),
),
),
),
),
),
),
],
),
),
);
}
return ListView(
physics: BouncingScrollPhysics(),
children: list,
],
),
);
}
},
);
}

Expand Down
120 changes: 51 additions & 69 deletions lib/ui/availability/availability_display.dart
Original file line number Diff line number Diff line change
Expand Up @@ -41,71 +41,8 @@ class AvailabilityDisplay extends StatelessWidget {
}

Widget buildAvailabilityBars(BuildContext context) {
List<Widget> locations = [];
// add any children the model contains to the listview
if (model.subLocations!.isNotEmpty) {
for (SubLocations subLocation in model.subLocations!) {
locations.add(
SizedBox(
height: 75,
child: Center(
child: ListTile(
onTap: () => subLocation.floors!.length > 0
? Navigator.pushNamed(
context, RoutePaths.AvailabilityDetailedView,
arguments: subLocation)
: print('_handleIconClick: no subLocations'),
visualDensity: VisualDensity.compact,
trailing: subLocation.floors!.length > 0
? Icon(Icons.arrow_forward_ios_rounded)
: null,
title: Text(
subLocation.name!,
style: TextStyle(
fontSize: LOCATION_FONT_SIZE,
),
),
subtitle: Column(
children: <Widget>[
Align(
alignment: Alignment.centerLeft,
child: Text(
(100 * percentAvailability(subLocation))
.toInt()
.toString() +
'% Busy',
// style: TextStyle(color: Colors.black),
)),
Align(
alignment: Alignment.centerLeft,
child: SizedBox(
height: PROGRESS_BAR_HEIGHT,
width: PROGRESS_BAR_WIDTH,
child: ClipRRect(
borderRadius: BorderRadius.circular(BORDER_RADIUS),
child: LinearProgressIndicator(
value: percentAvailability(subLocation) as double?,
backgroundColor: Colors.grey[BACKGROUND_GREY_SHADE],
valueColor: AlwaysStoppedAnimation<Color>(
setIndicatorColor(
percentAvailability(subLocation),
),
),
),
),
),
),
],
),
),
),
),
);
}
}

// if no children, return an error container
else {
if (model.subLocations!.isEmpty) {
return Container(
alignment: Alignment.center,
child: Text(
Expand All @@ -117,14 +54,59 @@ class AvailabilityDisplay extends StatelessWidget {
),
);
}
locations =
ListTile.divideTiles(tiles: locations, context: context).toList();

return Flexible(
child: Scrollbar(
child: ListView(
physics: NeverScrollableScrollPhysics(),
children: locations,
child: ListView.builder(
itemCount: model.subLocations!.length,
itemBuilder: (context, index) {
SubLocations subLocation = model.subLocations![index];
return ListTile(
onTap: () => subLocation.floors!.length > 0
? Navigator.pushNamed(
context, RoutePaths.AvailabilityDetailedView,
arguments: subLocation)
: print('_handleIconClick: no subLocations'),
visualDensity: VisualDensity.compact,
trailing: subLocation.floors!.length > 0
? Icon(Icons.arrow_forward_ios_rounded)
: null,
title: Text(
subLocation.name!,
style: TextStyle(
fontSize: LOCATION_FONT_SIZE,
),
),
subtitle: Column(
children: <Widget>[
Align(
alignment: Alignment.centerLeft,
child: Text(
(100 * percentAvailability(subLocation)).toInt().toString() +
'% Busy',
),
),
Align(
alignment: Alignment.centerLeft,
child: SizedBox(
height: PROGRESS_BAR_HEIGHT,
width: PROGRESS_BAR_WIDTH,
child: ClipRRect(
borderRadius: BorderRadius.circular(BORDER_RADIUS),
child: LinearProgressIndicator(
value: percentAvailability(subLocation) as double?,
backgroundColor: Colors.grey[BACKGROUND_GREY_SHADE],
valueColor: AlwaysStoppedAnimation<Color>(
setIndicatorColor(percentAvailability(subLocation)),
),
),
),
),
),
],
),
);
},
),
),
);
Expand Down
19 changes: 10 additions & 9 deletions lib/ui/classes/upcoming_classes.dart
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,17 @@ class UpcomingCoursesList extends StatelessWidget {

Widget buildListOfCourses(
List<SectionData> data, int? selectedCourse, BuildContext context) {
List<Widget> listOfCourses = List.generate(data.length, (int index) {
return buildTile(index, selectedCourse, data[index], context);
});
return Container(
constraints:
BoxConstraints(maxHeight: MediaQuery.of(context).size.height * 0.3),
child: ListView(
children: listOfCourses,
shrinkWrap: true,
));
constraints:
BoxConstraints(maxHeight: MediaQuery.of(context).size.height * 0.3),
child: ListView.builder(
itemCount: data.length,
itemBuilder: (context, index) {
return buildTile(index, selectedCourse, data[index], context);
},
shrinkWrap: true,
),
);
}

Widget buildTile(
Expand Down
2 changes: 1 addition & 1 deletion lib/ui/common/card_container.dart
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ class CardContainer extends StatelessWidget {
// web cards are still sized with static values
return Container(
width: double.infinity,
constraints: BoxConstraints(minHeight: cardMinHeight, maxHeight: 340),
constraints: BoxConstraints(minHeight: cardMinHeight, maxHeight: 260),
child: child(),
);
} else if (titleText == "Parking") {
Expand Down
15 changes: 6 additions & 9 deletions lib/ui/common/image_loader.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import 'package:cached_network_image/cached_network_image.dart';

class ImageLoader extends StatelessWidget {
final String? url;
Expand All @@ -17,23 +18,19 @@ class ImageLoader extends StatelessWidget {
width: 0,
height: 0,
)
: Image.network(
url!,
: CachedNetworkImage(
imageUrl: url!,
width: fullSize ? null : width,
height: fullSize ? null : height,
loadingBuilder: (BuildContext context, Widget child,
ImageChunkEvent? loadingProgress) {
if (loadingProgress == null) return child;
progressIndicatorBuilder: (context, url, downloadProgress) {
return Center(
child: CircularProgressIndicator(
color: Theme.of(context).colorScheme.secondary,
value: loadingProgress.expectedTotalBytes != null
? loadingProgress.cumulativeBytesLoaded /
loadingProgress.expectedTotalBytes!
: null,
value: downloadProgress.progress,
),
);
},
errorWidget: (context, url, error) => Icon(Icons.error),
);
}
}
Loading