From 2d3fded5c4886c72b3245e25ba71266b4b684e77 Mon Sep 17 00:00:00 2001 From: Amitosh Swain Mahapatra Date: May 30 2018 07:02:31 +0000 Subject: Add documentation to providers and pages --- diff --git a/src/app/app.component.ts b/src/app/app.component.ts index a115f57..67a0859 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -9,18 +9,24 @@ import { WomenPage } from '../pages/women/women'; import { FirstPage } from '../pages/first/first'; import { SplashScreen } from '@ionic-native/splash-screen'; +/** + * Entrypoint for the Fedora App + */ @Component({ templateUrl: 'app.html', }) export class App { + /** + * Contains the pages that constitute this app + */ pages: { title: string, component: any }[]; + rootPage: any; @ViewChild('content') nav: NavController; constructor(platform: Platform, splashScreen: SplashScreen) { - // used for an example of ngFor and navigation this.pages = [ { title: 'Home', component: FirstPage }, { title: 'Magazine', component: MagazinePage }, @@ -40,9 +46,14 @@ export class App { }); } - openPage(page) { - // Reset the content nav to have just this page - // we wouldn't want the back button to show in this scenario + /** + * Navigate to a new page + * + * @param page page to navigate to + */ + openPage(page): void { + // Reset the content nav to have just this page we wouldn't want the back + // button to show in this scenario this.nav.push(page.component); } } diff --git a/src/app/config.env.ts.example b/src/app/config.env.ts.example index 19cfb63..8b44a9b 100644 --- a/src/app/config.env.ts.example +++ b/src/app/config.env.ts.example @@ -8,7 +8,8 @@ const FB_CONFIG = { }; const TWITTER_CONFIG = { - BEARER_TOKEN: 'AAAAAEXAMPLEAAAAAAAAMmWwEXAMPLE9tGRvIFnIR8XYXmIFTFaEGagjX0%3Dup2JDIi9hjbCJKGaEGDqkLMtYSGumkyMa6SbwXx0FMB1vOlvN0' + BEARER_TOKEN: 'AAAAAEXAMPLEAAAAAAAAMmWwEXAMPLE9tGRvIFnIR8XYXmEXAMpLEGgjX0%3' + + 'Dup2JDExAmplEJKGaEXAmpLetYSGumkyExAMplEx0FMB1vOlvN0' }; const ENV = { diff --git a/src/app/main.ts b/src/app/main.ts index 060f649..059feec 100644 --- a/src/app/main.ts +++ b/src/app/main.ts @@ -4,6 +4,8 @@ import { AppModule } from './app.module'; import { enableProdMode } from '@angular/core'; if (ENV.PROD) { + // Enable Angular prod mode in PROD builds only. Angular Prod mode drops a + // considerable amount of assertions enableProdMode(); } diff --git a/src/pages/ask/ask.html b/src/pages/ask/ask.html index ba6ba7a..be8ca8a 100644 --- a/src/pages/ask/ask.html +++ b/src/pages/ask/ask.html @@ -39,17 +39,17 @@ - {{ question.vote }} + {{ question.score }}
VOTE
- {{ question.answers }} + {{ question.answerCount }}
Ans
- {{ question.view }} + {{ question.viewCount }}
VIEW
diff --git a/src/pages/ask/ask.ts b/src/pages/ask/ask.ts index e61edc1..ce42a88 100644 --- a/src/pages/ask/ask.ts +++ b/src/pages/ask/ask.ts @@ -1,21 +1,24 @@ import { Component } from '@angular/core'; import { SocialSharing } from '@ionic-native/social-sharing'; - import { Browser } from '../../providers/browser/browser'; -import { AskFedoraService } from '../../providers/ask-fedora/ask-fedora'; - -/* - Generated class for the AskPage page. +import { AskFedoraService, Question } from '../../providers/ask-fedora/ask-fedora'; - See http://ionicframework.com/docs/v2/components/#navigation for more info on - Ionic pages and navigation. -*/ +/** + * Shows latest questions from Ask Fedora + * + * Fetches latest 30 questions from Ask Fedora and displays the questions, the + * answers and the number of votes each question receives. + */ @Component({ templateUrl: 'ask.html', providers: [Browser, AskFedoraService], }) export class AskPage { - private questions: any; + + /** + * Stores list of displayed questions + */ + private questions: Question[]; constructor(private browser: Browser, private askFedora: AskFedoraService, private socialSharing: SocialSharing) { @@ -26,7 +29,10 @@ export class AskPage { this.updateQuestions(); } - updateQuestions() { + /** + * Fetch a list of latest questions using Ask Fedora API. + */ + updateQuestions(): void { this.askFedora .getQuestions() .subscribe(questions => { @@ -34,16 +40,31 @@ export class AskPage { }); } - openQuestion(event) { - this.browser.open(event.link); + /** + * Open a question in a browser. + * + * Opens question in an in-app browser in mobile app and in a new tab on desktop. + * + * @param question question to open + */ + openQuestion(question: Question): void { + this.browser.open(question.link); } - shareQuestion(event) { + /** + * Share the question using a third-party app installed in the user's device + * + * Allows to share the question using apps like WhatsApp, Facebook, or any app that + * exposes a share interface to the underlying OS. + * + * @param question question to share + */ + shareQuestion(question: Question): void { this.socialSharing.share( - event.title, - event.title, + question.content, + question.title, null, - event.link + question.link ); } } diff --git a/src/pages/calendar/calendar.ts b/src/pages/calendar/calendar.ts index 1ec2f2b..45f372e 100644 --- a/src/pages/calendar/calendar.ts +++ b/src/pages/calendar/calendar.ts @@ -1,24 +1,39 @@ import { Component } from '@angular/core'; import { Calendar } from '@ionic-native/calendar'; -import { FedoCalService, Calendar as CalendarType } from '../../providers/fedo-cal/fedo-cal'; +import { FedoCalService, Calendar as CalendarType, Meeting } from '../../providers/fedo-cal/fedo-cal'; -/* - Generated class for the CalendarPage page. - - See http://ionicframework.com/docs/v2/components/#navigation for more info on - Ionic pages and navigation. -*/ +/** + * We default to the QA calendar + */ const DEFAULT_CALENDAR = 'QA'; +/** + * The FedoCal interface + * + * Shows the list of calendars availabe on FedoCal and the meetings of each + * calendar. Also allows to add meetings from the calendar to the system calendar. + */ @Component({ templateUrl: 'calendar.html', providers: [FedoCalService, Calendar] }) export class CalendarPage { + + /** + * List of calendars in FedoCal + */ private calendars: CalendarType[]; - private meetings: Array; + + /** + * List of meetings in the selected calendar + */ + private meetings: Meeting[]; + + /** + * ID of the selected calendar + */ private selectedCalendar: string; constructor(private fedoCal: FedoCalService, private calendar: Calendar) { @@ -33,7 +48,10 @@ export class CalendarPage { this.updateMeetings(); } - updateCalendars() { + /** + * Update the list of calendars from FedoCal + */ + updateCalendars(): void { this.fedoCal .getCalendars() .subscribe(calendars => { @@ -41,7 +59,10 @@ export class CalendarPage { }); } - updateMeetings() { + /** + * Update the list of meetings for the selected calendar + */ + updateMeetings(): void { this.fedoCal .getMeetings(this.selectedCalendar) .subscribe(meetings => { @@ -49,13 +70,18 @@ export class CalendarPage { }); } - addToCalendar(event) { + /** + * Add a FedoCal meeting to the system calendar + * + * @param meeting meeting to add to the calendar + */ + addToCalendar(meeting:Meeting): void { this.calendar.createEventInteractively( - event.name, - event.location, - event.real_description, - event.datetime_start, - event.datetime_end + meeting.name, + meeting.location, + meeting.description, + meeting.time, + meeting.timeEnd ); } } diff --git a/src/pages/first/first.ts b/src/pages/first/first.ts index ed1f25e..6a8b464 100644 --- a/src/pages/first/first.ts +++ b/src/pages/first/first.ts @@ -1,46 +1,47 @@ import { Component } from '@angular/core'; import { NavController } from 'ionic-angular'; -import { Browser } from '../../providers/browser/browser'; import { MagazinePage } from '../magazine/magazine'; import { AskPage } from '../ask/ask'; import { CalendarPage } from '../calendar/calendar'; import { SocialPage } from '../social/social'; -/* - Generated class for the MagazinePage page. - - See http://ionicframework.com/docs/v2/components/#navigation for more info on - Ionic pages and navigation. -*/ +/** + * Home page of the Fedora App + */ @Component({ templateUrl: 'first.html', }) export class FirstPage { - private posts: Array; - - constructor(private nav: NavController, private browser: Browser) { - this.posts = []; - } - openPost(event) { - this.browser.open(event.link); + constructor(private nav: NavController) { } - openMag() { + /** + * Navigate to Fedora Magazine section + */ + openMag(): void { this.nav.push(MagazinePage); } - openAsk() { + + /** + * Navigate to Ask Fedora section + */ + openAsk(): void { this.nav.push(AskPage); } - openSocial() { + + /** + * Navigate to Fedora Social section + */ + openSocial(): void { this.nav.push(SocialPage); } - openCal() { - this.nav.push(CalendarPage); - } - - login(event) { + /** + * Navigate to Fedora Calendar section + */ + openCal(): void { + this.nav.push(CalendarPage); } } diff --git a/src/pages/magazine/magazine.ts b/src/pages/magazine/magazine.ts index b0c724f..172d1ca 100644 --- a/src/pages/magazine/magazine.ts +++ b/src/pages/magazine/magazine.ts @@ -4,17 +4,18 @@ import { SocialSharing } from '@ionic-native/social-sharing'; import { Browser } from '../../providers/browser/browser'; import { FedoraMagazineService, Post } from '../../providers/fedora-magazine/fedora-magazine'; -/* - Generated class for the MagazinePage page. - - See http://ionicframework.com/docs/v2/components/#navigation for more info on - Ionic pages and navigation. -*/ +/** + * Shows latest posts from Fedora Magazine + */ @Component({ templateUrl: 'magazine.html', providers: [FedoraMagazineService], }) export class MagazinePage { + + /** + * List of posts from Fedora Magazine + */ private posts: Post[]; constructor(private browser: Browser, @@ -26,21 +27,39 @@ export class MagazinePage { this.updatePosts(); } - updatePosts() { + /** + * Fetch latest posts from Fedor Magazine API + */ + updatePosts(): void { this.fedoraMag.getPosts() .subscribe(posts => { this.posts = posts; }); } - openPost(event) { - this.browser.open(event.link); + /** + * Open a post in a browser + * + * Opens the post in an in-app browser in mobile app and in a new tab on desktop. + * + * @param post post to open + */ + openPost(post:Post): void { + this.browser.open(post.link); } - sharePost(event) { + /** + * Share the post using a third-party app installed in the user's device + * + * Allows to share the post using apps like WhatsApp, Facebook, or any app that + * exposes a share interface to the underlying OS. + * + * @param post post to share + */ + sharePost(post:Post): void { this.socialSharing.share( - event.title, event.title, - null, event.link + post.excerpt, post.title, + null, post.permalink ); } } diff --git a/src/pages/social/social.ts b/src/pages/social/social.ts index 185dd8d..3f79a04 100644 --- a/src/pages/social/social.ts +++ b/src/pages/social/social.ts @@ -12,19 +12,22 @@ const HANDLE = { TWITTER: 'fedora_qa', }; -/* - Generated class for the SocialPage page. +const DEFAULT_POST_TITLE = 'Update from Fedora Project'; - See http://ionicframework.com/docs/v2/components/#navigation for more info on - Ionic pages and navigation. -*/ +/** + * Shows updates from the social media channels of Fedora + */ @Component({ templateUrl: 'social.html', providers: [FacebookProvider, TwitterProvider], }) export class SocialPage { + /** + * List of posts from different social media channels + */ private posts: Post[]; + constructor(private browser: Browser, private fb: FacebookProvider, private twitter: TwitterProvider, private socialSharing: SocialSharing) { this.posts = []; @@ -34,23 +37,45 @@ export class SocialPage { this.updatePosts(); } - private updatePosts() { + /** + * Fetch posts from social media channels + * + * Currently, we fetch posts from Facebook and Twitter + */ + private updatePosts(): void { forkJoin(this.fb.getPosts(HANDLE.FB), this.twitter.getPosts(HANDLE.TWITTER)) .subscribe(values => { this.posts = [...values[0], ...values[1]] as Post[]; }); } - openPost(event) { - this.browser.open(event.link); + /** + * Open a post in a browser + * + * Opens the post in an in-app browser in mobile app and in a new tab on desktop. + * On some platforms, the post may directly open in the app of the social media + * service. + * + * @param post post to open + */ + openPost(post:Post): void { + this.browser.open(post.link); } - sharePost(event) { + /** + * Share the post using a third-party app installed in the user's device + * + * Allows to share the post using apps like WhatsApp, Facebook, or any app that + * exposes a share interface to the underlying OS. + * + * @param post post to share + */ + sharePost(post:Post): void { this.socialSharing.share( - event.title, - event.title, + post.content, + DEFAULT_POST_TITLE, null, - event.link + post.link ); } } diff --git a/src/pages/women/women.ts b/src/pages/women/women.ts index 7ef83df..0b037c9 100644 --- a/src/pages/women/women.ts +++ b/src/pages/women/women.ts @@ -1,11 +1,10 @@ import { Component } from '@angular/core'; -/* - Generated class for the MagazinePage page. - - See http://ionicframework.com/docs/v2/components/#navigation for more info on - Ionic pages and navigation. -*/ +/** + * Fedora Women section + * + * Under construction + */ @Component({ templateUrl: 'women.html', }) diff --git a/src/providers/ask-fedora/ask-fedora.ts b/src/providers/ask-fedora/ask-fedora.ts index 09afe00..1b62eef 100644 --- a/src/providers/ask-fedora/ask-fedora.ts +++ b/src/providers/ask-fedora/ask-fedora.ts @@ -2,45 +2,95 @@ import 'rxjs/add/operator/map'; import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { chooseEndpoint } from '../../utils'; +import { Observable } from 'rxjs/Observable'; +/** + * Ask Fedora API endpoint + * + * It does not support CORS so we have to proxy it through Ionic CLI during development + */ const ENDPOINT = chooseEndpoint('/ask-fedora', 'https://ask.fedoraproject.org/en/api/v1'); +/** + * A question on Ask Fedora + */ export interface Question { - id: string, + /** + * Question ID + */ + id: number, + + /** + * Question title + */ title: string, + + /** + * Permalink to the question + */ link: string, - answers: number, + + /** + * Number of answers to this question + */ + answerCount: number, + + /** + * Content of this question + */ content: string, - timestamp: Date, + + /** + * Time of posting of this question + */ + addedAt: Date, + + /** + * Tags associated with this question + */ tags: string[], - view: number, - vote: number, -} + /** + * Number of views registered by this question + */ + viewCount: number, + + /** + * Total score for this question + * + * It is the sum of all up-votes and down-votes. + */ + score: number, +} -/* - Generated class for the AskFedora provider. - See https://angular.io/docs/ts/latest/guide/dependency-injection.html - for more info on providers and Angular 2 DI. -*/ +/** + * Service for Ask Fedora API + * + * Provides a read-only access to questions and answers posted in Ask Fedora. + */ @Injectable() export class AskFedoraService { constructor(private http: HttpClient) { } - getQuestions() { + /** + * Fetch a list of questions from Ask Fedora API + * + * @returns Observable which emits an array of questions + */ + getQuestions(): Observable { return this.http.get(`${ENDPOINT}/questions/`) - .map((data: any) => data.questions.map(q => ({ + .map((data: any) => (data.questions as any[]).map(q => ({ id: q.id, title: q.title, link: q.url, - answers: q.answer_count, + answerCount: q.answer_count, content: q.summary, - timestamp: q.added_at, + addedAt: new Date(parseInt(q.added_at, 10)), tags: q.tags, - view: q.view_count, - vote: q.score, + viewCount: q.view_count, + score: q.score, }))); } } diff --git a/src/providers/browser/browser.ts b/src/providers/browser/browser.ts index 2b3715d..b038007 100644 --- a/src/providers/browser/browser.ts +++ b/src/providers/browser/browser.ts @@ -4,28 +4,36 @@ import { SpinnerDialog } from '@ionic-native/spinner-dialog'; import { Toast } from '@ionic-native/toast'; import { Platform } from 'ionic-angular'; -/* - Generated class for the Browser provider. - - See https://angular.io/docs/ts/latest/guide/dependency-injection.html - for more info on providers and Angular 2 DI. -*/ +/** + * Wrapper over in-app browser to show a busy indicator while loading web content + */ @Injectable() export class Browser { + private browser: InAppBrowserObject; + constructor(private platform: Platform, private inAppBrowser: InAppBrowser, private spinnerDialog: SpinnerDialog, private toast: Toast) { this.browser = null; } + /** + * Called when content loading is started + */ private startHandler = () => { this.spinnerDialog.show(); } + /** + * Called when content loading is complete + */ private stopHandler = () => { this.spinnerDialog.hide(); } + /** + * Called when there is an error while loading content + */ private errorHandler = (error) => { this.toast.showShortBottom('Something went wrong.'); this.browser.close(); @@ -33,8 +41,15 @@ export class Browser { this.browser = null; } - open(link) { - const browser: InAppBrowserObject = this.inAppBrowser.create(encodeURI(link), '_blank'); + /** + * Open a link in an in-app browser + * + * Attaches lifecycle callbacks only on platforms which support them. + * + * @param link link to open in a an in-app browser + */ + public open(link): void { + const browser = this.inAppBrowser.create(encodeURI(link), '_blank'); this.browser = browser; // Cordova does not fire the events in browser. diff --git a/src/providers/fedo-cal/fedo-cal.ts b/src/providers/fedo-cal/fedo-cal.ts index ce0c7bb..f753d4a 100644 --- a/src/providers/fedo-cal/fedo-cal.ts +++ b/src/providers/fedo-cal/fedo-cal.ts @@ -8,15 +8,31 @@ import { HttpClient } from '@angular/common/http'; import { Observable } from 'rxjs/Observable'; import { chooseEndpoint } from '../../utils'; - +/** + * FedoCal API endpoint + * + * It does not support CORS so we have to proxy it through Ionic CLI during development + */ const ENDPOINT = chooseEndpoint('/fedocal', 'https://apps.fedoraproject.org/calendar/api'); +/** + * Date format for display + */ const DATE_FORMAT = 'dddd, MMMM Do YYYY'; + +/** + * Time format for display + */ const TIME_FORMAT = 'h:mm A z'; -/* - Convert title to capital case, but skip special names like FESCo, FAmSCo, i18n -*/ +/** + * Convert calendar name from API to a value suitable for display + * + * Convert title to capital case, but skip special names like FESCo, FAmSCo, i18n + * + * @param name Calendar name as in API + * @returns Friendly representation of the name + */ function calendarNameToDisplayName(name: string): string { switch (name) { case 'i18n': @@ -28,43 +44,114 @@ function calendarNameToDisplayName(name: string): string { } } +/** + * A calendar on FedoCal + * + * Calendars are assoicated with a group / SIG / or event. They contain a number + * of recurring meetings or events. + */ export interface Calendar { + + /** + * Name of calendar, as expressed in the API + * + * Serves as an ID for API calls. + */ realName: string, + + /** + * Human friendly calendar name obtained from `realName` + */ displayName: string, + + /** + * Calendar's description + */ description: string, + + /** + * Group with admin previlages for this calendar + */ adminGroup: string, + + /** + * Group with edit previlages for this calendar + */ editorGroup: string, + + /** + * Contact person for this calendar + */ contact: string, + + /** + * Whether the calendar is enabled + */ enabled: boolean, } +/** + * A meeting on a FedoCal calendar + */ export interface Meeting { + + /** + * Name of the meeting + */ name: string, + + /** + * Description of the meeting + */ description: string, + + /** + * Where is the meeting happening? + * + * Can be an IRC channel or even a physical location. + */ location: string, + + /** + * Meeting start time + */ time: Date, + + /** + * Meeting end time + */ timeEnd: Date, + + /** + * Start time formatted for display + */ displayTime: { dateString: string, timeString: string, }, + + /** + * End time formatted for display + */ displayTimeEnd: { dateString: string, timeString: string, } } -/* - Generated class for the FedoCal provider. - - See https://angular.io/docs/ts/latest/guide/dependency-injection.html - for more info on providers and Angular 2 DI. -*/ +/** + * Service for FedoCal + */ @Injectable() export class FedoCalService { constructor(private http: HttpClient) { } + /** + * Fetch the list of calendars from FedoCal API + * + * @returns Observable which emits an array of calendars + */ getCalendars(): Observable { return this.http.get(`${ENDPOINT}/calendars/`) .map((data: any) => @@ -79,7 +166,13 @@ export class FedoCalService { }))); } - getMeetings(calendar): Observable { + /** + * Fetch the list of meetings for a given FedoCal calendar name + * + * @param calendar FedoCal calendar name + * @returns Observable which emits an array of meetings + */ + getMeetings(calendar:string): Observable { return this.http.get(`${ENDPOINT}/meetings/`, { params: { calendar: calendar } }) .map((data: any) => data.meetings.map(m => { @@ -92,6 +185,7 @@ export class FedoCalService { time: mTime.toDate(), timeEnd: mTimeEnd.toDate(), displayTime: { + // Format momentjs object to the defined format for display dateString: mTime.format(DATE_FORMAT), timeString: mTime.format(TIME_FORMAT) }, @@ -105,8 +199,15 @@ export class FedoCalService { } } - -function dateToMoment(date, time, timezone) { +/** + * Convert a date consisting of date, time and timezone as different strings to + * a single momentjs date + * + * @param date Date string + * @param time Time string + * @param timezone Timezone identifier + */ +function dateToMoment(date:string, time:string, timezone:string) { const m = moment.tz(`${date} ${time}`, timezone).tz('UTC'); return m; } diff --git a/src/providers/fedora-magazine/fedora-magazine.ts b/src/providers/fedora-magazine/fedora-magazine.ts index df22c3b..8b52bd9 100644 --- a/src/providers/fedora-magazine/fedora-magazine.ts +++ b/src/providers/fedora-magazine/fedora-magazine.ts @@ -6,60 +6,75 @@ import { chooseEndpoint } from '../../utils'; const ENDPOINT = chooseEndpoint('/fedora-magazine', 'https://fedoramagazine.org/wp-json/wp/v2'); +/** + * Represents a post on Fedora Magazine + */ export interface Post { + /** + * Unique ID of the post, supplied by the CMS + */ id: number, + + /** + * A sluggified link to the post + */ link: string, + + /** + * Permalink to the post + */ + permalink:string, + + /** + * Post title + */ title: string, - image: any, + + /** + * URL to the featured image of the post + */ + image: string, + + /** + * A short excerpt of the post + */ excerpt: string, + + /** + * The content of the post + */ content: string, - date: Date -} -/* - Generated class for the FedoraMag provider. + /** + * Time of publication + */ + publishedAt: Date +} - See https://angular.io/docs/ts/latest/guide/dependency-injection.html - for more info on providers and Angular 2 DI. -*/ +/** + * Service for fetching posts from Fedora Magazine API + */ @Injectable() export class FedoraMagazineService { constructor(private http: HttpClient) { } + /** + * Fetch the list of latest posts on Fedora Magazine + * + * @returns Observable which emits an array of posts + */ getPosts(): Observable { return this.http.get(`${ENDPOINT}/posts`) .map((data: any[]) => data.map((post: any) => ({ id: post.id, link: post.link, + permalink: post.guid.rendered, title: post.title.rendered, image: post.featured_media, excerpt: post.excerpt.rendered, content: post.content.rendered, - date: new Date(post.date_gmt+'Z'), + publishedAt: new Date(post.date_gmt+'Z'), }))); } } - - /* getMedia_url(posts) { - if (!_.isEmpty(this.media_url[posts])) { - return Promise.resolve(this.media_url[posts]); - } - - return new Promise((resolve, reject) => { - this.request.get(this.API.media_url,{ posts : posts }) - .then(data => { - this.media_url[posts] = _.map(data, i => { - // var excerpt = p.excerpt.rendered; - var img_url = { - img_id: i.id, - img_link: i.guid.rendered, - }; - //image_url = func_url(post.image); - return post; - }); - - return resolve(this.posts); - }).catch(reject); - }); - }*/ diff --git a/src/providers/social/facebook.ts b/src/providers/social/facebook.ts index 48e4ea0..a3192b4 100644 --- a/src/providers/social/facebook.ts +++ b/src/providers/social/facebook.ts @@ -7,20 +7,30 @@ import { SocialProvider, Post, FACEBOOK } from './social'; import { Observable } from 'rxjs/Observable'; import { Observer } from 'rxjs/Observer'; -/* - Generated class for the Fb provider. - - See https://angular.io/docs/ts/latest/guide/dependency-injection.html - for more info on providers and Angular 2 DI. -*/ +/** + * Service for Facebook API + * + * Allows to fetch data from Facebook pages. + */ @Injectable() export class FacebookProvider implements SocialProvider { + + /** + * Facebook API instance + */ private fb: Facebook; constructor() { this.fb = new Facebook(ENV.FB_CONFIG); } - private api(uri) { + /** + * Perform a call to a Facebook API using the library + * + * Converts callback-style error handling to observables. + * + * @param uri Facebook API URI + */ + private api(uri:string) { return Observable.create((emitter: Observer) => { this.fb.api(uri, res => { if (!res || res.error) { @@ -33,6 +43,13 @@ export class FacebookProvider implements SocialProvider { }); } + /** + * Fetch the list of posts for a given Facebook page + * + * @param page ID of the Facebook page + * @param args Extra args for pagination etc. + * @returns Observable which emits an array of Facebook posts + */ public getPosts(page: string, args?): Observable { return this.api(`${page}/posts`) .map(res => { diff --git a/src/providers/social/social.ts b/src/providers/social/social.ts index 8832ffe..10b17b7 100644 --- a/src/providers/social/social.ts +++ b/src/providers/social/social.ts @@ -1,19 +1,51 @@ import { Observable } from "rxjs/Observable"; +/** + * ID for facebook provider + */ export const FACEBOOK = 'facebook'; + +/** + * ID for twitter provider + */ export const TWITTER = 'twitter'; +/** + * Represents a post in social media service + */ export interface Post { + /** + * Service specific unique ID + */ id:string, + + /** + * Origin of the post + */ origin:string, + + /** + * Link to the app of website of the social media service hosting the post + */ link:string, - content:string, -} -export interface GetPostExtraArgs { - offset?: string, + /** + * Text content of the post + */ + content:string, } +/** + * A generic social media provider + */ export interface SocialProvider { - getPosts(resID: string, args?:GetPostExtraArgs): Observable + + /** + * Fetch the list of posts for a given service specific resource ID + * + * @param resID service specific resource IS + * @param args Extra args for pagination etc. + * @returns Observable which emits an array of posts + */ + getPosts(resID: string, args?:{ offset?: string }): Observable } diff --git a/src/providers/social/twitter.ts b/src/providers/social/twitter.ts index 490c566..444b7d6 100644 --- a/src/providers/social/twitter.ts +++ b/src/providers/social/twitter.ts @@ -9,17 +9,21 @@ import ENV from '@environment'; const ENDPOINT = chooseEndpoint('/twitter', 'https://api.twitter.com/1.1'); -/* - Generated class for the Twitter provider. - - See https://angular.io/docs/ts/latest/guide/dependency-injection.html - for more info on providers and Angular 2 DI. -*/ +/** + * Service for Twitter API + */ @Injectable() export class TwitterProvider implements SocialProvider { constructor(private http: HttpClient) { } + /** + * Fetch the list of tweets for a given Twitter handle + * + * @param handle Twitter handle whose tweets to load + * @param args Extra args for pagination etc. + * @returns Observable which emits an array of tweets + */ public getPosts(handle: string, args?): Observable { return this.http.get(`${ENDPOINT}/statuses/user_timeline.json`, { params: { screen_name: handle }, diff --git a/src/utils.ts b/src/utils.ts index 25bc712..77c0b48 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,8 +1,9 @@ /** * Choose appropriate API end point or the proxy to avoid CORS in Ionic dev server + * * @param devServerEndpoint endpoint in Ionic dev server - * @param appEndpoint endpoint to use in real application + * @param appEndpoint endpoint to use in real application */ export function chooseEndpoint(devServerEndpoint:string, appEndpoint:string) { // courtesy: https://forum.ionicframework.com/t/check-if-run-on-emulator-dev-production-or-livereload/71845/9