Skip to content

Commit

Permalink
Implement all Feed UI components (#118)
Browse files Browse the repository at this point in the history
* Homepage story and schedule UI implementation.

* Fixed tests for feed viewmodel.

Refer feed_viewmodel_test.dart for examples on how to write unit tests
for the functions that use Task to call functions from the API service.
Added test for failure case in stories API call.

* Implemet MM articles UI and improve test coverage.

This commit adds UI implementation for MM articles, changes the story
component widget to match the design spec, and adds tests for Margin,
Failure. Unused code and tests related to API classes have been removed.

* Feed view implemented.

Feed view UI components implemented:
[x] Stories
[x] Schedule
[x] Stories this week
[x] Upcoming Events

Internet permission added to AndroidManifest.xml, Story component has a
border gradient now. Files for exporting the files in some folders are
added to make documentation generation work correctly.

* Implement suggested changes.

- Deleted test/.test_coverage.dart
- Use Future.wait() in FeedViewmodel.initialise().
  • Loading branch information
Thesmader authored Jan 27, 2021
1 parent 7d7e104 commit 4899063
Show file tree
Hide file tree
Showing 46 changed files with 836 additions and 434 deletions.
2 changes: 2 additions & 0 deletions elaichi/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ doc/api/
# If you don't generate coverage info locally you can remove this line.
coverage/

test/.test_coverage.dart

# Avoid committing generated Javascript files:
*.dart.js
*.info.json # Produced by the --dump-info flag.
Expand Down
1 change: 1 addition & 0 deletions elaichi/android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ if (flutterVersionName == null) {
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
apply plugin: 'com.google.gms.google-services'

def keyStoreProperties = new Properties()
def keyStorePropertiesFile = rootProject.file('key.properties')
Expand Down
1 change: 1 addition & 0 deletions elaichi/android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.dscnitrourkela.elaichi">
<uses-permission android:name="android.permission.INTERNET" />
<!-- io.flutter.app.FlutterApplication is an android.app.Application that
calls FlutterMain.startInitialization(this); in its onCreate method.
In most cases you can leave this as-is, but you if you want to provide
Expand Down
1 change: 1 addition & 0 deletions elaichi/android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ buildscript {
dependencies {
classpath 'com.android.tools.build:gradle:3.5.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath 'com.google.gms:google-services:4.3.4'
}
}

Expand Down
Binary file added elaichi/assets/icons/avenue_icons.ttf
Binary file not shown.
Binary file removed elaichi/assets/images/dsc.png
Binary file not shown.
3 changes: 2 additions & 1 deletion elaichi/assets/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@
"welcome": "Welcome to NITR Central",
"homeTitle": "Your Feed",
"timeTable": "Timetable",
"openCalendar": "Open Calendar"
"openCalendar": "Open Calendar",
"thisWeekTitle": "Stories This Week"
}
1 change: 1 addition & 0 deletions elaichi/lib/app/colors.dart
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ class AppColors {
static const Color darkAnnouncementDocBackground =
Color.fromRGBO(238, 109, 109, 0.05);
static const Color unselectedIconColor = Color.fromRGBO(196, 196, 196, 1.0);
static const Color cardHeader = Color.fromRGBO(79, 79, 79, 1.0);

//icons
static const Color calendarIcon = Color.fromRGBO(47, 128, 237, 1.0);
Expand Down
20 changes: 20 additions & 0 deletions elaichi/lib/app/icons.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import 'package:flutter/widgets.dart';

/// Contains all custom icons used in the app.
class AppIcons {
AppIcons._();

static const _kAvenueFont = 'Avenue';

/// Monday Morning icon data.
static const IconData mmIcon = IconData(0xe500, fontFamily: _kAvenueFont);

/// Feed icon for BottomNavigationBar.
static const IconData feed = IconData(0xe902, fontFamily: _kAvenueFont);

/// Explore icon for BottomNavigationBar.
static const IconData explore = IconData(0xe901, fontFamily: _kAvenueFont);

/// Campus icon for BottomNavigationBar.
static const IconData campus = IconData(0xe900, fontFamily: _kAvenueFont);
}
2 changes: 0 additions & 2 deletions elaichi/lib/app/locator.config.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 5 additions & 2 deletions elaichi/lib/app/styles.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,11 @@ class TextStyles {
fontSize: 16.0, fontWeight: FontWeight.w600, height: 1.225);

/// Used in Smaller section headers, TabBar, subject/event title in schedule.
static TextStyle get heading2 =>
const TextStyle(fontSize: 14.0, height: 1.4, fontWeight: FontWeight.w600);
static TextStyle get heading2 => const TextStyle(
fontSize: 14.0,
height: 1.4,
fontWeight: FontWeight.w600,
color: AppColors.bodyText);

/// Used for Bold/grey/colored text paired with body1, course code/club,
/// time name in schedule, desgination of club members
Expand Down
23 changes: 2 additions & 21 deletions elaichi/lib/datamodels/api_models.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import 'package:flutter/widgets.dart';

import 'user.dart';

class Club {
///
Club(
Expand Down Expand Up @@ -72,25 +74,6 @@ class Event {
final String picture;
}

/// Defines data model for login response.
class LoginResponse {
/// Creates an instance of [LoginResponse].
LoginResponse({
this.success = true,
this.userId,
this.message,
});

/// The boolean value specifying if login was successful.
final bool success;

/// The firebase user ID.
final String userId;

/// The error/success message.
final String message;
}

///
class ScheduleEvent {
///
Expand All @@ -106,5 +89,3 @@ class ScheduleEvent {
final String title;
final String contact;
}

class User {}
6 changes: 6 additions & 0 deletions elaichi/lib/datamodels/datamodels.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
library datamodels;

export 'api_models.dart';
export 'auth_user.dart';
export 'data.dart';
export 'user.dart';
3 changes: 2 additions & 1 deletion elaichi/lib/generated/codegen_loader.g.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ class CodegenLoader extends AssetLoader{
"welcome": "Welcome to NITR Central",
"homeTitle": "Your Feed",
"timeTable": "Timetable",
"openCalendar": "Open Calendar"
"openCalendar": "Open Calendar",
"thisWeekTitle": "Stories This Week"
};
static const Map<String, Map<String,dynamic>> mapLocales = {"en": en};
}
1 change: 1 addition & 0 deletions elaichi/lib/generated/locale_keys.g.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@ abstract class LocaleKeys {
static const homeTitle = 'homeTitle';
static const timeTable = 'timeTable';
static const openCalendar = 'openCalendar';
static const thisWeekTitle = 'thisWeekTitle';

}
230 changes: 230 additions & 0 deletions elaichi/lib/graphql/schema.graphql
Original file line number Diff line number Diff line change
@@ -0,0 +1,230 @@
directive @cacheControl(
maxAge: Int
scope: CacheControlScope
) on FIELD_DEFINITION | OBJECT | INTERFACE
# Exposes a URL that specifies the behaviour of this scalar.
directive @specifiedBy(
# The URL that specifies the behaviour of this scalar.
url: String!
) on SCALAR
type AccessLevel {
id: ID
level: String
name: String
relation: String
club: Club
user: User
}

input AccessLevelInputType {
level: String
name: String
relation: String
club: ID
user: ID
}

type ActiveStory {
id: ID
assetType: String
storyAsset: String
authorName: String
authorLogo: String
}

enum CacheControlScope {
PUBLIC
PRIVATE
}

type Club {
id: ID
clubName: String
memberAccess: [AccessLevel]
facAd: String
logo: String
events: [Event]
society: String
domain: String
}

input ClubInputType {
clubName: String
memberAccess: [AccessLevelInputType]
facAd: String
logo: String
events: [ID]
society: String
domain: String
}

# A date-time string at UTC, such as 2007-12-03T10:15:30Z, compliant with the
# `date-time` format outlined in section 5.6 of the RFC 3339 profile of the ISO
# 8601 standard for representation of dates and times using the Gregorian calendar.
scalar DateTime

type Error {
code: String
message: String
token: String
}

type ErrorClass {
message: String!
code: String!
}

type Event {
id: ID
organizer: Club
eventName: String
startDateTime: String
venue: Venue
endDateTime: String
registrationPrice: Int
registrationCount: Int
otherDescription: String
attendees: [User]
announcements: String
link: String
picture: String
}

input EventInputType {
organizer: ID
eventName: String
startDateTime: String
venue: ID
endDateTime: String
registrationPrice: Int
registrationCount: Int
otherDescription: String
attendees: [ID]
announcements: String
link: String
picture: String
}

type Mutation {
authUser(user: UserInputType): User
updateUser(user: UserInputType): User
deleteUser(id: ID): User
addEvent(event: EventInputType): Event
updateEvent(id: ID, event: EventInputType): Event
deleteEvent(id: ID): Event
addClub(club: ClubInputType): Club
updateClub(id: ID, club: ClubInputType): Club
deleteClub(id: ID): Club
addVenue(venue: VenueInputType): Venue
updateVenue(id: ID, venue: VenueInputType): Venue
deleteVenue(id: ID): Venue
addStory(story: StoryInputType): StoryResult
}

type Query {
users(
name: String
username: String
gmailAuthMail: String
instituteId: String
mobile: String
emergencyContact: String
): [UserResult]
userByUsername(username: String): UserResult
userById(id: String): UserResult
events(
id: ID
eventName: String
facAd: String
logo: String
society: String
domain: String
): [Event]
eventByName(name: String): Event
eventById(id: String): Event
clubs(
id: ID
clubName: String
facAd: String
logo: String
society: String
domain: String
): [Club]
clubByName(name: String): Club
clubById(id: String): Club
venues(venue: VenueInputType): [Venue]
venueByName(name: String): Venue
venueById(id: String): Venue
currentStories: [ActiveStory]
storiesByField(
id: ID
author: ID
event: ID
asset: String
assetType: String
description: String
): [Story]
deleteStory(id: ID): Response
}

type Response {
success: Boolean
}

type Story {
id: ID
author: Club
event: Event
asset: String
assetType: String
description: String
createdAt: DateTime
}

input StoryInputType {
author: ID
event: ID
asset: String
assetType: String
description: String
}

union StoryResult = Story | ErrorClass
# The `Upload` scalar type represents a file upload.
scalar Upload

type User {
id: ID
name: String
username: String
gmailAuthMail: String
clubAccess: [AccessLevel]
instituteId: String
mobile: String
emergencyContact: String
displayPicture: String
}

input UserInputType {
name: String
username: String
gmailAuthMail: String
instituteId: String
mobile: String
emergencyContact: String
displayPicture: String
}

union UserOrError = User | Error
union UserResult = User | ErrorClass
type Venue {
id: ID
name: String
description: String
}

input VenueInputType {
name: String
description: String
}

Loading

0 comments on commit 4899063

Please sign in to comment.