Skip to content

Commit

Permalink
pull from upstream master
Browse files Browse the repository at this point in the history
  • Loading branch information
richtwin567 committed Aug 28, 2020
2 parents 07a5c87 + 711aa98 commit a2144bc
Show file tree
Hide file tree
Showing 11 changed files with 687 additions and 0 deletions.
22 changes: 22 additions & 0 deletions lib/models/from_postgres/scholarship/scholarship.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
class Scholarship {
//Attributes of the Class
String name;
String description;
String details;

//Constructor for the Scholarship Class
Scholarship({this.name, this.description, this.details});

//Getter Methods for the attributes
String get scholarshipName => name;
String get scholarshipDescription => description;
String get scholarshipDetails => details;

//This method converts a json map into an Scholarship Object
factory Scholarship.fromJson(Map<String, dynamic> parsedJSON) {
return Scholarship(
name: parsedJSON['name'],
description: parsedJSON['description'],
details: parsedJSON['details']);
}
}
116 changes: 116 additions & 0 deletions lib/models/scholarshiplist.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
import 'package:fst_app_flutter/models/from_postgres/scholarship/scholarship.dart';
import 'package:fst_app_flutter/utils/debouncer.dart';
import 'package:flutter/foundation.dart';

// Defines the model for the manager of the list of Scholarships
class ScholarshipList with ChangeNotifier{

bool isPerformingRequest; // illustrates if the manager is processing a request
bool isAtEnd; // signifies if the list has shown all the data
bool hasResults; // signifies if the search results has any data
int start; //signifies the start index in the original list of scholarship from data request

List<Scholarship> scholarships; // original list of scholarships from http requests
List<Scholarship> current; // The current list which is used in the list view
List<Scholarship> viewList; // The paginated list of scholarship

final int size = 10; //The amount of scholarships added during each request

ScholarshipList({scholarships}){
this.scholarships = scholarships;
start = 0;
isPerformingRequest = false;
isAtEnd = false;
hasResults = true;


//If the original list of scholarships has a length less than size then it will assigned the list as the viewList
//otherwise it will get a list with length of size from the original list and assign it to viewlist
if(scholarships.length <= size){
viewList = scholarships.getRange(start, scholarships.length).toList();
start += (scholarships.length - start);
}else{
viewList = scholarships.getRange(start, start+size).toList();
start += size;
}
current = viewList;
}

//Getter Methods
List<Scholarship> get scholarList => current;
bool get atEnd => isAtEnd;
bool get doesHaveResults => hasResults;
bool get processRequests => isPerformingRequest;
bool get isViewList => current == viewList;

//Factory Method for converting json into the model used
factory ScholarshipList.fromJson(List<dynamic> parsedJson) {
List<Scholarship> lst = new List<Scholarship>();
lst = parsedJson.map((i) => Scholarship.fromJson(i)).toList();
return new ScholarshipList(
scholarships: lst,
);
}

//Function which searches to see if the query is contained in the Scholarship Name
//Possibly could be refined for better searching methods
void search(String query){

current = scholarships.where((p) => p.scholarshipName.toLowerCase().contains(query.toLowerCase())).toList();

if(current.isEmpty){
current = [Scholarship(name:"No Search Results")];
hasResults = false;
}else if(query == ""){
current = viewList;
hasResults = true;
}else{
hasResults = true;
}


notifyListeners();

}

void getMoreData() async{

if (!isPerformingRequest) {

isPerformingRequest = true;

notifyListeners();

List<Scholarship> newEntries; //new entries of scholarships for the paginated list

if((scholarships.length - start) == 0){
newEntries = [];
}else if((scholarships.length - start) < size){
newEntries = scholarships.getRange(start, scholarships.length).toList();
start += (scholarships.length - start);
}else {
newEntries = scholarships.getRange(start, start+size).toList();
start += size;
}

if (newEntries.isEmpty){
isAtEnd = true;
}

await Debouncer.wait();

viewList.addAll(newEntries);
isPerformingRequest = false;

notifyListeners();
}
}

//switches the list to the paginated list
void switchList(){
current = viewList;
notifyListeners();
}


}
3 changes: 3 additions & 0 deletions lib/routing/generate_routes.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import 'package:fst_app_flutter/screens/contact_screen/contact_detail_page.dart'
import 'package:fst_app_flutter/screens/contact_screen/contact_view.dart';
import 'package:fst_app_flutter/screens/homescreen/home_view.dart';
import 'package:fst_app_flutter/screens/map_screen/map_view.dart';
import 'package:fst_app_flutter/screens/scholarship_screen/scholarship_view.dart';
import 'routes.dart';

/// Handles routing in the app
Expand All @@ -16,6 +17,8 @@ class Router {
return MaterialPageRoute(builder: (context) => ContactView());
case contactDetailRoute:
return SlideUpPageRoute(page: ContactDetailPage(settings.arguments));
case scholarshipRoute:
return MaterialPageRoute(builder: (context) => ScholarshipView());
case appPreferencesRoute:
return MaterialPageRoute(builder: (context) => AppPreferencesView());
case mapRoute:
Expand Down
3 changes: 3 additions & 0 deletions lib/routing/routes.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ const contactRoute = '/contact';
/// [ContactDetailPage] route
const contactDetailRoute = '/contactDetail';

/// [ScholarshipView] route
const scholarshipRoute = '/scholarship';

/// [AppPreferencesView] route
const appPreferencesRoute = '/appConfig';

Expand Down
49 changes: 49 additions & 0 deletions lib/screens/scholarship_screen/local_widget/scholarcard.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import 'package:flutter/material.dart';
import 'package:fst_app_flutter/models/from_postgres/scholarship/scholarship.dart';
import 'package:fst_app_flutter/screens/scholarship_screen/scholarship_details.dart';

class ScholarCard extends StatelessWidget {
final Scholarship scholarship;

const ScholarCard({this.scholarship});

@override
Widget build(BuildContext context) {
return Card(
elevation: 2,
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0),
child: ListTile(
title: Text(scholarship.scholarshipName),
trailing: Icon(
Icons.arrow_forward_ios,
size: 18,
),
onTap: () {
Navigator.of(context).push(_buildTransition());
},
),
),
);
}

PageRouteBuilder _buildTransition(){
return PageRouteBuilder(
pageBuilder: (context, animation, secondaryAnimation) => ScholarshipDetails(current: scholarship),
transitionDuration: Duration(milliseconds: 500,),
transitionsBuilder: (context, animation, secondaryAnimation, child){
animation = CurvedAnimation(
curve: Curves.easeOut,
parent: animation,
);
return SlideTransition(
position: Tween(
begin: Offset(1.0,0.0),
end: Offset(0.0, 0.0)
).animate(animation),
child: child,
);
},
);
}
}
126 changes: 126 additions & 0 deletions lib/screens/scholarship_screen/scholarship_details.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:fst_app_flutter/models/preferences/theme_model.dart';
import 'package:fst_app_flutter/models/from_postgres/scholarship/scholarship.dart';

class ScholarshipDetails extends StatefulWidget {
final Scholarship current;

ScholarshipDetails({this.current});

@override
_ScholarshipDetailsState createState() => _ScholarshipDetailsState();
}

class _ScholarshipDetailsState extends State<ScholarshipDetails> {
final _scroll = ScrollController();
bool isDark;

void dispose(){
_scroll.dispose();
super.dispose();
}

Widget _buildAppBar(){
return AppBar(
title: Text(widget.current.scholarshipName),
backgroundColor: isDark ? Colors.grey.shade800 : Theme.of(context).primaryColor,
elevation: 0,
);
}

Widget _buildHeader(String text){
return Container(
padding: const EdgeInsets.symmetric(vertical: 5),
decoration: BoxDecoration(
color: isDark ? Colors.grey.shade800 : Theme.of(context).primaryColor,
borderRadius: BorderRadius.all(Radius.circular(20)),
),
child: Center(
child: Text(
text,
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 22,
color: Colors.white,
fontFamily: "Monsterrat",
),
),
),
);
}

Widget _setParagraph(String text){
return SelectableText.rich(
TextSpan(
style: TextStyle(
fontSize: 15,
fontFamily: "Monsterrat",
color: isDark ? Colors.white : Colors.black,
),
children: <TextSpan>[
TextSpan(
text: text,
),
],
),
showCursor: true,
cursorColor: