First Commit
This commit is contained in:
commit
feb864dc47
170 changed files with 4671 additions and 0 deletions
283
hackatonApp/www/js/app.js
Normal file
283
hackatonApp/www/js/app.js
Normal file
|
|
@ -0,0 +1,283 @@
|
|||
// Ionic Starter App
|
||||
|
||||
angular.module('underscore', [])
|
||||
.factory('_', function() {
|
||||
return window._; // assumes underscore has already been loaded on the page
|
||||
});
|
||||
|
||||
// angular.module is a global place for creating, registering and retrieving Angular modules
|
||||
// 'starter' is the name of this angular module example (also set in a <body> attribute in index.html)
|
||||
// the 2nd parameter is an array of 'requires'
|
||||
angular.module('your_app_name', [
|
||||
'ionic',
|
||||
'angularMoment',
|
||||
'your_app_name.controllers',
|
||||
'your_app_name.directives',
|
||||
'your_app_name.filters',
|
||||
'your_app_name.services',
|
||||
'your_app_name.factories',
|
||||
'your_app_name.config',
|
||||
'your_app_name.views',
|
||||
'underscore',
|
||||
'ngMap',
|
||||
'ngResource',
|
||||
'ngCordova',
|
||||
'slugifier',
|
||||
'ionic.contrib.ui.tinderCards',
|
||||
'youtube-embed'
|
||||
])
|
||||
|
||||
.run(function($ionicPlatform, PushNotificationsService, $rootScope, $ionicConfig, $timeout) {
|
||||
|
||||
$ionicPlatform.on("deviceready", function(){
|
||||
// Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
|
||||
// for form inputs)
|
||||
if(window.cordova && window.cordova.plugins.Keyboard) {
|
||||
cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
|
||||
}
|
||||
if(window.StatusBar) {
|
||||
StatusBar.styleDefault();
|
||||
}
|
||||
|
||||
PushNotificationsService.register();
|
||||
});
|
||||
|
||||
// This fixes transitions for transparent background views
|
||||
$rootScope.$on("$stateChangeStart", function(event, toState, toParams, fromState, fromParams){
|
||||
if(toState.name.indexOf('auth.walkthrough') > -1)
|
||||
{
|
||||
// set transitions to android to avoid weird visual effect in the walkthrough transitions
|
||||
$timeout(function(){
|
||||
$ionicConfig.views.transition('android');
|
||||
$ionicConfig.views.swipeBackEnabled(false);
|
||||
console.log("setting transition to android and disabling swipe back");
|
||||
}, 0);
|
||||
}
|
||||
});
|
||||
$rootScope.$on("$stateChangeSuccess", function(event, toState, toParams, fromState, fromParams){
|
||||
if(toState.name.indexOf('app.feeds-categories') > -1)
|
||||
{
|
||||
// Restore platform default transition. We are just hardcoding android transitions to auth views.
|
||||
$ionicConfig.views.transition('platform');
|
||||
// If it's ios, then enable swipe back again
|
||||
if(ionic.Platform.isIOS())
|
||||
{
|
||||
$ionicConfig.views.swipeBackEnabled(true);
|
||||
}
|
||||
console.log("enabling swipe back and restoring transition to platform default", $ionicConfig.views.transition());
|
||||
}
|
||||
});
|
||||
|
||||
$ionicPlatform.on("resume", function(){
|
||||
PushNotificationsService.register();
|
||||
});
|
||||
|
||||
})
|
||||
|
||||
|
||||
.config(function($stateProvider, $urlRouterProvider, $ionicConfigProvider) {
|
||||
$stateProvider
|
||||
|
||||
//INTRO
|
||||
.state('auth', {
|
||||
url: "/auth",
|
||||
templateUrl: "views/auth/auth.html",
|
||||
abstract: true,
|
||||
controller: 'AuthCtrl'
|
||||
})
|
||||
|
||||
.state('auth.walkthrough', {
|
||||
url: '/walkthrough',
|
||||
templateUrl: "views/auth/walkthrough.html"
|
||||
})
|
||||
|
||||
.state('auth.login', {
|
||||
url: '/login',
|
||||
templateUrl: "views/auth/login.html",
|
||||
controller: 'LoginCtrl'
|
||||
})
|
||||
|
||||
.state('auth.signup', {
|
||||
url: '/signup',
|
||||
templateUrl: "views/auth/signup.html",
|
||||
controller: 'SignupCtrl'
|
||||
})
|
||||
|
||||
.state('auth.forgot-password', {
|
||||
url: "/forgot-password",
|
||||
templateUrl: "views/auth/forgot-password.html",
|
||||
controller: 'ForgotPasswordCtrl'
|
||||
})
|
||||
|
||||
.state('app', {
|
||||
url: "/app",
|
||||
abstract: true,
|
||||
templateUrl: "views/app/side-menu.html",
|
||||
controller: 'AppCtrl'
|
||||
})
|
||||
|
||||
//MISCELLANEOUS
|
||||
.state('app.miscellaneous', {
|
||||
url: "/miscellaneous",
|
||||
views: {
|
||||
'menuContent': {
|
||||
templateUrl: "views/app/miscellaneous/miscellaneous.html"
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
.state('app.maps', {
|
||||
url: "/miscellaneous/maps",
|
||||
views: {
|
||||
'menuContent': {
|
||||
templateUrl: "views/app/miscellaneous/maps.html",
|
||||
controller: 'MapsCtrl'
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
.state('app.image-picker', {
|
||||
url: "/miscellaneous/image-picker",
|
||||
views: {
|
||||
'menuContent': {
|
||||
templateUrl: "views/app/miscellaneous/image-picker.html",
|
||||
controller: 'ImagePickerCtrl'
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
//LAYOUTS
|
||||
.state('app.layouts', {
|
||||
url: "/layouts",
|
||||
views: {
|
||||
'menuContent': {
|
||||
templateUrl: "views/app/layouts/layouts.html"
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
.state('app.tinder-cards', {
|
||||
url: "/layouts/tinder-cards",
|
||||
views: {
|
||||
'menuContent': {
|
||||
templateUrl: "views/app/layouts/tinder-cards.html",
|
||||
controller: 'TinderCardsCtrl'
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
.state('app.slider', {
|
||||
url: "/layouts/slider",
|
||||
views: {
|
||||
'menuContent': {
|
||||
templateUrl: "views/app/layouts/slider.html"
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
//FEEDS
|
||||
.state('app.feeds-categories', {
|
||||
url: "/feeds-categories",
|
||||
views: {
|
||||
'menuContent': {
|
||||
templateUrl: "views/app/feeds/feeds-categories.html",
|
||||
controller: 'FeedsCategoriesCtrl'
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
.state('app.category-feeds', {
|
||||
url: "/category-feeds/:categoryId",
|
||||
views: {
|
||||
'menuContent': {
|
||||
templateUrl: "views/app/feeds/category-feeds.html",
|
||||
controller: 'CategoryFeedsCtrl'
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
.state('app.feed-entries', {
|
||||
url: "/feed-entries/:categoryId/:sourceId",
|
||||
views: {
|
||||
'menuContent': {
|
||||
templateUrl: "views/app/feeds/feed-entries.html",
|
||||
controller: 'FeedEntriesCtrl'
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
//WORDPRESS
|
||||
.state('app.wordpress', {
|
||||
url: "/wordpress",
|
||||
views: {
|
||||
'menuContent': {
|
||||
templateUrl: "views/app/wordpress/wordpress.html",
|
||||
controller: 'WordpressCtrl'
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
.state('app.post', {
|
||||
url: "/wordpress/:postId",
|
||||
views: {
|
||||
'menuContent': {
|
||||
templateUrl: "views/app/wordpress/wordpress_post.html",
|
||||
controller: 'WordpressPostCtrl'
|
||||
}
|
||||
},
|
||||
resolve: {
|
||||
post_data: function(PostService, $ionicLoading, $stateParams) {
|
||||
$ionicLoading.show({
|
||||
template: 'Loading post ...'
|
||||
});
|
||||
|
||||
var postId = $stateParams.postId;
|
||||
return PostService.getPost(postId);
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
//OTHERS
|
||||
.state('app.settings', {
|
||||
url: "/settings",
|
||||
views: {
|
||||
'menuContent': {
|
||||
templateUrl: "views/app/settings.html",
|
||||
controller: 'SettingsCtrl'
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
.state('app.forms', {
|
||||
url: "/forms",
|
||||
views: {
|
||||
'menuContent': {
|
||||
templateUrl: "views/app/forms.html"
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
.state('app.profile', {
|
||||
url: "/profile",
|
||||
views: {
|
||||
'menuContent': {
|
||||
templateUrl: "views/app/profile.html"
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
.state('app.bookmarks', {
|
||||
url: "/bookmarks",
|
||||
views: {
|
||||
'menuContent': {
|
||||
templateUrl: "views/app/bookmarks.html",
|
||||
controller: 'BookMarksCtrl'
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
;
|
||||
|
||||
// if none of the above states are matched, use this as the fallback
|
||||
$urlRouterProvider.otherwise('/auth/walkthrough');
|
||||
});
|
||||
5
hackatonApp/www/js/config.js
Normal file
5
hackatonApp/www/js/config.js
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
angular.module('your_app_name.config', [])
|
||||
.constant('WORDPRESS_API_URL', 'http://wordpress.startapplabs.com/blog/api/')
|
||||
.constant('GCM_SENDER_ID', '574597432927')
|
||||
|
||||
;
|
||||
465
hackatonApp/www/js/controllers.js
Normal file
465
hackatonApp/www/js/controllers.js
Normal file
|
|
@ -0,0 +1,465 @@
|
|||
angular.module('your_app_name.controllers', [])
|
||||
|
||||
.controller('AuthCtrl', function($scope, $ionicConfig) {
|
||||
|
||||
})
|
||||
|
||||
// APP
|
||||
.controller('AppCtrl', function($scope, $ionicConfig) {
|
||||
|
||||
})
|
||||
|
||||
//LOGIN
|
||||
.controller('LoginCtrl', function($scope, $state, $templateCache, $q, $rootScope) {
|
||||
$scope.doLogIn = function(){
|
||||
$state.go('app.feeds-categories');
|
||||
};
|
||||
|
||||
$scope.user = {};
|
||||
|
||||
$scope.user.email = "john@doe.com";
|
||||
$scope.user.pin = "12345";
|
||||
|
||||
// We need this for the form validation
|
||||
$scope.selected_tab = "";
|
||||
|
||||
$scope.$on('my-tabs-changed', function (event, data) {
|
||||
$scope.selected_tab = data.title;
|
||||
});
|
||||
|
||||
})
|
||||
|
||||
.controller('SignupCtrl', function($scope, $state) {
|
||||
$scope.user = {};
|
||||
|
||||
$scope.user.email = "john@doe.com";
|
||||
|
||||
$scope.doSignUp = function(){
|
||||
$state.go('app.feeds-categories');
|
||||
};
|
||||
})
|
||||
|
||||
.controller('ForgotPasswordCtrl', function($scope, $state) {
|
||||
$scope.recoverPassword = function(){
|
||||
$state.go('app.feeds-categories');
|
||||
};
|
||||
|
||||
$scope.user = {};
|
||||
})
|
||||
|
||||
.controller('RateApp', function($scope) {
|
||||
$scope.rateApp = function(){
|
||||
if(ionic.Platform.isIOS()){
|
||||
//you need to set your own ios app id
|
||||
AppRate.preferences.storeAppURL.ios = '1234555553>';
|
||||
AppRate.promptForRating(true);
|
||||
}else if(ionic.Platform.isAndroid()){
|
||||
//you need to set your own android app id
|
||||
AppRate.preferences.storeAppURL.android = 'market://details?id=ionFB';
|
||||
AppRate.promptForRating(true);
|
||||
}
|
||||
};
|
||||
})
|
||||
|
||||
.controller('SendMailCtrl', function($scope) {
|
||||
$scope.sendMail = function(){
|
||||
cordova.plugins.email.isAvailable(
|
||||
function (isAvailable) {
|
||||
// alert('Service is not available') unless isAvailable;
|
||||
cordova.plugins.email.open({
|
||||
to: 'envato@startapplabs.com',
|
||||
cc: 'hello@startapplabs.com',
|
||||
// bcc: ['john@doe.com', 'jane@doe.com'],
|
||||
subject: 'Greetings',
|
||||
body: 'How are you? Nice greetings from IonFullApp'
|
||||
});
|
||||
}
|
||||
);
|
||||
};
|
||||
})
|
||||
|
||||
.controller('MapsCtrl', function($scope, $ionicLoading) {
|
||||
|
||||
$scope.info_position = {
|
||||
lat: 43.07493,
|
||||
lng: -89.381388
|
||||
};
|
||||
|
||||
$scope.center_position = {
|
||||
lat: 43.07493,
|
||||
lng: -89.381388
|
||||
};
|
||||
|
||||
$scope.my_location = "";
|
||||
|
||||
$scope.$on('mapInitialized', function(event, map) {
|
||||
$scope.map = map;
|
||||
});
|
||||
|
||||
$scope.centerOnMe= function(){
|
||||
|
||||
$scope.positions = [];
|
||||
|
||||
$ionicLoading.show({
|
||||
template: 'Loading...'
|
||||
});
|
||||
|
||||
// with this function you can get the user’s current position
|
||||
// we use this plugin: https://github.com/apache/cordova-plugin-geolocation/
|
||||
navigator.geolocation.getCurrentPosition(function(position) {
|
||||
var pos = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
|
||||
$scope.current_position = {lat: pos.G,lng: pos.K};
|
||||
$scope.my_location = pos.G+", "+pos.K;
|
||||
$scope.map.setCenter(pos);
|
||||
$ionicLoading.hide();
|
||||
});
|
||||
};
|
||||
})
|
||||
|
||||
.controller('AdsCtrl', function($scope, $ionicActionSheet, AdMob, iAd) {
|
||||
|
||||
$scope.manageAdMob = function() {
|
||||
|
||||
// Show the action sheet
|
||||
var hideSheet = $ionicActionSheet.show({
|
||||
//Here you can add some more buttons
|
||||
buttons: [
|
||||
{ text: 'Show Banner' },
|
||||
{ text: 'Show Interstitial' }
|
||||
],
|
||||
destructiveText: 'Remove Ads',
|
||||
titleText: 'Choose the ad to show',
|
||||
cancelText: 'Cancel',
|
||||
cancel: function() {
|
||||
// add cancel code..
|
||||
},
|
||||
destructiveButtonClicked: function() {
|
||||
console.log("removing ads");
|
||||
AdMob.removeAds();
|
||||
return true;
|
||||
},
|
||||
buttonClicked: function(index, button) {
|
||||
if(button.text == 'Show Banner')
|
||||
{
|
||||
console.log("show banner");
|
||||
AdMob.showBanner();
|
||||
}
|
||||
|
||||
if(button.text == 'Show Interstitial')
|
||||
{
|
||||
console.log("show interstitial");
|
||||
AdMob.showInterstitial();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
$scope.manageiAd = function() {
|
||||
|
||||
// Show the action sheet
|
||||
var hideSheet = $ionicActionSheet.show({
|
||||
//Here you can add some more buttons
|
||||
buttons: [
|
||||
{ text: 'Show iAd Banner' },
|
||||
{ text: 'Show iAd Interstitial' }
|
||||
],
|
||||
destructiveText: 'Remove Ads',
|
||||
titleText: 'Choose the ad to show - Interstitial only works in iPad',
|
||||
cancelText: 'Cancel',
|
||||
cancel: function() {
|
||||
// add cancel code..
|
||||
},
|
||||
destructiveButtonClicked: function() {
|
||||
console.log("removing ads");
|
||||
iAd.removeAds();
|
||||
return true;
|
||||
},
|
||||
buttonClicked: function(index, button) {
|
||||
if(button.text == 'Show iAd Banner')
|
||||
{
|
||||
console.log("show iAd banner");
|
||||
iAd.showBanner();
|
||||
}
|
||||
if(button.text == 'Show iAd Interstitial')
|
||||
{
|
||||
console.log("show iAd interstitial");
|
||||
iAd.showInterstitial();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
};
|
||||
})
|
||||
|
||||
// FEED
|
||||
//brings all feed categories
|
||||
.controller('FeedsCategoriesCtrl', function($scope, $http) {
|
||||
$scope.feeds_categories = [];
|
||||
|
||||
$http.get('feeds-categories.json').success(function(response) {
|
||||
$scope.feeds_categories = response;
|
||||
});
|
||||
})
|
||||
|
||||
//bring specific category providers
|
||||
.controller('CategoryFeedsCtrl', function($scope, $http, $stateParams) {
|
||||
$scope.category_sources = [];
|
||||
|
||||
$scope.categoryId = $stateParams.categoryId;
|
||||
|
||||
$http.get('feeds-categories.json').success(function(response) {
|
||||
var category = _.find(response, {id: $scope.categoryId});
|
||||
$scope.categoryTitle = category.title;
|
||||
$scope.category_sources = category.feed_sources;
|
||||
});
|
||||
})
|
||||
|
||||
//this method brings posts for a source provider
|
||||
.controller('FeedEntriesCtrl', function($scope, $stateParams, $http, FeedList, $q, $ionicLoading, BookMarkService) {
|
||||
$scope.feed = [];
|
||||
|
||||
var categoryId = $stateParams.categoryId,
|
||||
sourceId = $stateParams.sourceId;
|
||||
|
||||
$scope.doRefresh = function() {
|
||||
|
||||
$http.get('feeds-categories.json').success(function(response) {
|
||||
|
||||
$ionicLoading.show({
|
||||
template: 'Loading entries...'
|
||||
});
|
||||
|
||||
var category = _.find(response, {id: categoryId }),
|
||||
source = _.find(category.feed_sources, {id: sourceId });
|
||||
|
||||
$scope.sourceTitle = source.title;
|
||||
|
||||
FeedList.get(source.url)
|
||||
.then(function (result) {
|
||||
$scope.feed = result.feed;
|
||||
$ionicLoading.hide();
|
||||
$scope.$broadcast('scroll.refreshComplete');
|
||||
}, function (reason) {
|
||||
$ionicLoading.hide();
|
||||
$scope.$broadcast('scroll.refreshComplete');
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
$scope.doRefresh();
|
||||
|
||||
$scope.bookmarkPost = function(post){
|
||||
$ionicLoading.show({ template: 'Post Saved!', noBackdrop: true, duration: 1000 });
|
||||
BookMarkService.bookmarkFeedPost(post);
|
||||
};
|
||||
})
|
||||
|
||||
// SETTINGS
|
||||
.controller('SettingsCtrl', function($scope, $ionicActionSheet, $state) {
|
||||
$scope.airplaneMode = true;
|
||||
$scope.wifi = false;
|
||||
$scope.bluetooth = true;
|
||||
$scope.personalHotspot = true;
|
||||
|
||||
$scope.checkOpt1 = true;
|
||||
$scope.checkOpt2 = true;
|
||||
$scope.checkOpt3 = false;
|
||||
|
||||
$scope.radioChoice = 'B';
|
||||
|
||||
// Triggered on a the logOut button click
|
||||
$scope.showLogOutMenu = function() {
|
||||
|
||||
// Show the action sheet
|
||||
var hideSheet = $ionicActionSheet.show({
|
||||
//Here you can add some more buttons
|
||||
// buttons: [
|
||||
// { text: '<b>Share</b> This' },
|
||||
// { text: 'Move' }
|
||||
// ],
|
||||
destructiveText: 'Logout',
|
||||
titleText: 'Are you sure you want to logout? This app is awsome so I recommend you to stay.',
|
||||
cancelText: 'Cancel',
|
||||
cancel: function() {
|
||||
// add cancel code..
|
||||
},
|
||||
buttonClicked: function(index) {
|
||||
//Called when one of the non-destructive buttons is clicked,
|
||||
//with the index of the button that was clicked and the button object.
|
||||
//Return true to close the action sheet, or false to keep it opened.
|
||||
return true;
|
||||
},
|
||||
destructiveButtonClicked: function(){
|
||||
//Called when the destructive button is clicked.
|
||||
//Return true to close the action sheet, or false to keep it opened.
|
||||
$state.go('auth.walkthrough');
|
||||
}
|
||||
});
|
||||
|
||||
};
|
||||
})
|
||||
|
||||
// TINDER CARDS
|
||||
.controller('TinderCardsCtrl', function($scope, $http) {
|
||||
|
||||
$scope.cards = [];
|
||||
|
||||
|
||||
$scope.addCard = function(img, name) {
|
||||
var newCard = {image: img, name: name};
|
||||
newCard.id = Math.random();
|
||||
$scope.cards.unshift(angular.extend({}, newCard));
|
||||
};
|
||||
|
||||
$scope.addCards = function(count) {
|
||||
$http.get('http://api.randomuser.me/?results=' + count).then(function(value) {
|
||||
angular.forEach(value.data.results, function (v) {
|
||||
$scope.addCard(v.user.picture.large, v.user.name.first + " " + v.user.name.last);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
$scope.addFirstCards = function() {
|
||||
$scope.addCard("https://dl.dropboxusercontent.com/u/30675090/envato/tinder-cards/left.png","Nope");
|
||||
$scope.addCard("https://dl.dropboxusercontent.com/u/30675090/envato/tinder-cards/right.png", "Yes");
|
||||
};
|
||||
|
||||
$scope.addFirstCards();
|
||||
$scope.addCards(5);
|
||||
|
||||
$scope.cardDestroyed = function(index) {
|
||||
$scope.cards.splice(index, 1);
|
||||
$scope.addCards(1);
|
||||
};
|
||||
|
||||
$scope.transitionOut = function(card) {
|
||||
console.log('card transition out');
|
||||
};
|
||||
|
||||
$scope.transitionRight = function(card) {
|
||||
console.log('card removed to the right');
|
||||
console.log(card);
|
||||
};
|
||||
|
||||
$scope.transitionLeft = function(card) {
|
||||
console.log('card removed to the left');
|
||||
console.log(card);
|
||||
};
|
||||
})
|
||||
|
||||
|
||||
// BOOKMARKS
|
||||
.controller('BookMarksCtrl', function($scope, $rootScope, BookMarkService, $state) {
|
||||
|
||||
$scope.bookmarks = BookMarkService.getBookmarks();
|
||||
|
||||
// When a new post is bookmarked, we should update bookmarks list
|
||||
$rootScope.$on("new-bookmark", function(event){
|
||||
$scope.bookmarks = BookMarkService.getBookmarks();
|
||||
});
|
||||
|
||||
$scope.goToFeedPost = function(link){
|
||||
window.open(link, '_blank', 'location=yes');
|
||||
};
|
||||
$scope.goToWordpressPost = function(postId){
|
||||
$state.go('app.post', {postId: postId});
|
||||
};
|
||||
})
|
||||
|
||||
// WORDPRESS
|
||||
.controller('WordpressCtrl', function($scope, $http, $ionicLoading, PostService, BookMarkService) {
|
||||
$scope.posts = [];
|
||||
$scope.page = 1;
|
||||
$scope.totalPages = 1;
|
||||
|
||||
$scope.doRefresh = function() {
|
||||
$ionicLoading.show({
|
||||
template: 'Loading posts...'
|
||||
});
|
||||
|
||||
//Always bring me the latest posts => page=1
|
||||
PostService.getRecentPosts(1)
|
||||
.then(function(data){
|
||||
$scope.totalPages = data.pages;
|
||||
$scope.posts = PostService.shortenPosts(data.posts);
|
||||
|
||||
$ionicLoading.hide();
|
||||
$scope.$broadcast('scroll.refreshComplete');
|
||||
});
|
||||
};
|
||||
|
||||
$scope.loadMoreData = function(){
|
||||
$scope.page += 1;
|
||||
|
||||
PostService.getRecentPosts($scope.page)
|
||||
.then(function(data){
|
||||
//We will update this value in every request because new posts can be created
|
||||
$scope.totalPages = data.pages;
|
||||
var new_posts = PostService.shortenPosts(data.posts);
|
||||
$scope.posts = $scope.posts.concat(new_posts);
|
||||
|
||||
$scope.$broadcast('scroll.infiniteScrollComplete');
|
||||
});
|
||||
};
|
||||
|
||||
$scope.moreDataCanBeLoaded = function(){
|
||||
return $scope.totalPages > $scope.page;
|
||||
};
|
||||
|
||||
$scope.bookmarkPost = function(post){
|
||||
$ionicLoading.show({ template: 'Post Saved!', noBackdrop: true, duration: 1000 });
|
||||
BookMarkService.bookmarkWordpressPost(post);
|
||||
};
|
||||
|
||||
$scope.doRefresh();
|
||||
})
|
||||
|
||||
// WORDPRESS POST
|
||||
.controller('WordpressPostCtrl', function($scope, post_data, $ionicLoading) {
|
||||
|
||||
$scope.post = post_data.post;
|
||||
$ionicLoading.hide();
|
||||
|
||||
$scope.sharePost = function(link){
|
||||
window.plugins.socialsharing.share('Check this post here: ', null, null, link);
|
||||
};
|
||||
})
|
||||
|
||||
|
||||
.controller('ImagePickerCtrl', function($scope, $rootScope, $cordovaCamera) {
|
||||
|
||||
$scope.images = [];
|
||||
|
||||
$scope.selImages = function() {
|
||||
|
||||
window.imagePicker.getPictures(
|
||||
function(results) {
|
||||
for (var i = 0; i < results.length; i++) {
|
||||
console.log('Image URI: ' + results[i]);
|
||||
$scope.images.push(results[i]);
|
||||
}
|
||||
if(!$scope.$$phase) {
|
||||
$scope.$apply();
|
||||
}
|
||||
}, function (error) {
|
||||
console.log('Error: ' + error);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
$scope.removeImage = function(image) {
|
||||
$scope.images = _.without($scope.images, image);
|
||||
};
|
||||
|
||||
$scope.shareImage = function(image) {
|
||||
window.plugins.socialsharing.share(null, null, image);
|
||||
};
|
||||
|
||||
$scope.shareAll = function() {
|
||||
window.plugins.socialsharing.share(null, null, $scope.images);
|
||||
};
|
||||
})
|
||||
|
||||
;
|
||||
374
hackatonApp/www/js/directives.js
Normal file
374
hackatonApp/www/js/directives.js
Normal file
|
|
@ -0,0 +1,374 @@
|
|||
angular.module('your_app_name.directives', [])
|
||||
|
||||
.directive('myTabs', function() {
|
||||
return {
|
||||
restrict: 'E',
|
||||
transclude: true,
|
||||
scope: {},
|
||||
controller: function($scope) {
|
||||
var tabs = $scope.tabs = [];
|
||||
|
||||
$scope.select = function(tab) {
|
||||
angular.forEach(tabs, function(tab) {
|
||||
tab.selected = false;
|
||||
});
|
||||
tab.selected = true;
|
||||
$scope.$emit('my-tabs-changed', tab);
|
||||
};
|
||||
|
||||
this.addTab = function(tab) {
|
||||
if (tabs.length === 0) {
|
||||
$scope.select(tab);
|
||||
}
|
||||
tabs.push(tab);
|
||||
};
|
||||
},
|
||||
templateUrl: 'views/common/my-tabs.html'
|
||||
};
|
||||
})
|
||||
|
||||
.directive('myTab', function() {
|
||||
return {
|
||||
require: '^myTabs',
|
||||
restrict: 'E',
|
||||
transclude: true,
|
||||
scope: {
|
||||
title: '@'
|
||||
},
|
||||
link: function(scope, element, attrs, tabsCtrl) {
|
||||
tabsCtrl.addTab(scope);
|
||||
},
|
||||
templateUrl: 'views/common/my-tab.html'
|
||||
};
|
||||
})
|
||||
|
||||
.directive('validPin', function($http) {
|
||||
return {
|
||||
require: 'ngModel',
|
||||
link: function(scope, ele, attrs, c) {
|
||||
scope.$watch(attrs.ngModel, function(pinValue) {
|
||||
// $http({
|
||||
// method: 'POST',
|
||||
// url: '/api/check/' + attrs.validPin,
|
||||
// data: {'pin': attrs.validPin}
|
||||
// }).success(function(data, status, headers, cfg) {
|
||||
// c.$setValidity('valid-pin', data.isValid);
|
||||
// }).error(function(data, status, headers, cfg) {
|
||||
// c.$setValidity('valid-pin', false);
|
||||
// });
|
||||
if(pinValue=="12345")
|
||||
{
|
||||
c.$setValidity('valid-pin', true);
|
||||
}
|
||||
else
|
||||
{
|
||||
c.$setValidity('valid-pin', false);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
})
|
||||
|
||||
|
||||
.directive('showHideContainer', function(){
|
||||
return {
|
||||
scope: {
|
||||
},
|
||||
controller: function($scope, $element, $attrs) {
|
||||
$scope.show = false;
|
||||
|
||||
$scope.toggleType = function($event){
|
||||
$event.stopPropagation();
|
||||
$event.preventDefault();
|
||||
|
||||
$scope.show = !$scope.show;
|
||||
|
||||
// Emit event
|
||||
$scope.$broadcast("toggle-type", $scope.show);
|
||||
};
|
||||
},
|
||||
templateUrl: 'views/common/show-hide-password.html',
|
||||
restrict: 'A',
|
||||
replace: false,
|
||||
transclude: true
|
||||
};
|
||||
})
|
||||
|
||||
|
||||
.directive('showHideInput', function(){
|
||||
return {
|
||||
scope: {
|
||||
},
|
||||
link: function(scope, element, attrs) {
|
||||
// listen to event
|
||||
scope.$on("toggle-type", function(event, show){
|
||||
var password_input = element[0],
|
||||
input_type = password_input.getAttribute('type');
|
||||
|
||||
if(!show)
|
||||
{
|
||||
password_input.setAttribute('type', 'password');
|
||||
}
|
||||
|
||||
if(show)
|
||||
{
|
||||
password_input.setAttribute('type', 'text');
|
||||
}
|
||||
});
|
||||
},
|
||||
require: '^showHideContainer',
|
||||
restrict: 'A',
|
||||
replace: false,
|
||||
transclude: false
|
||||
};
|
||||
})
|
||||
|
||||
|
||||
.directive('biggerText', function($ionicGesture) {
|
||||
return {
|
||||
restrict: 'A',
|
||||
link: function(scope, element, attrs) {
|
||||
$ionicGesture.on('touch', function(event){
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
|
||||
var text_element = document.querySelector(attrs.biggerText),
|
||||
root_element = document.querySelector(".menu-content"),
|
||||
current_size_str = window.getComputedStyle(text_element, null).getPropertyValue('font-size'),
|
||||
current_size = parseFloat(current_size_str),
|
||||
new_size = Math.min((current_size+2), 24),
|
||||
new_size_str = new_size + 'px';
|
||||
|
||||
root_element.classList.remove("post-size-"+current_size_str);
|
||||
root_element.classList.add("post-size-"+new_size_str);
|
||||
}, element);
|
||||
}
|
||||
};
|
||||
})
|
||||
|
||||
.directive('smallerText', function($ionicGesture) {
|
||||
return {
|
||||
restrict: 'A',
|
||||
link: function(scope, element, attrs) {
|
||||
$ionicGesture.on('touch', function(event){
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
|
||||
var text_element = document.querySelector(attrs.smallerText),
|
||||
root_element = document.querySelector(".menu-content"),
|
||||
current_size_str = window.getComputedStyle(text_element, null).getPropertyValue('font-size'),
|
||||
current_size = parseFloat(current_size_str),
|
||||
new_size = Math.max((current_size-2), 12),
|
||||
new_size_str = new_size + 'px';
|
||||
|
||||
root_element.classList.remove("post-size-"+current_size_str);
|
||||
root_element.classList.add("post-size-"+new_size_str);
|
||||
}, element);
|
||||
}
|
||||
};
|
||||
})
|
||||
|
||||
.directive('ionicYoutubeVideo', function($timeout, $ionicPlatform, youtubeEmbedUtils) {
|
||||
return {
|
||||
restrict: 'E',
|
||||
scope: {
|
||||
videoId: '@'
|
||||
},
|
||||
controller: function($scope, $element, $attrs) {
|
||||
$scope.playerVars = {
|
||||
rel: 0,
|
||||
showinfo: 0
|
||||
};
|
||||
$ionicPlatform.on("pause", function(){
|
||||
var yt_ready = youtubeEmbedUtils.ready;
|
||||
if(yt_ready)
|
||||
{
|
||||
$scope.yt_video.stopVideo();
|
||||
}
|
||||
});
|
||||
},
|
||||
templateUrl: 'views/common/ionic-youtube-video.html',
|
||||
replace: false
|
||||
};
|
||||
})
|
||||
|
||||
.directive('postContent', function($timeout, _, $compile) {
|
||||
return {
|
||||
restrict: 'A',
|
||||
scope: {},
|
||||
link: function(scope, element, attrs) {
|
||||
/**
|
||||
* JavaScript function to match (and return) the video Id
|
||||
* of any valid Youtube Url, given as input string.
|
||||
* @author: Stephan Schmitz <eyecatchup@gmail.com>
|
||||
* @url: http://stackoverflow.com/a/10315969/624466
|
||||
*/
|
||||
// Ver: https://regex101.com/r/tY9jN6/1
|
||||
function ytVidId(url) {
|
||||
var p = /^(?:https?:\/\/)?(?:www\.)?(?:youtu\.be\/|youtube\.com\/(?:embed\/|v\/|watch\?v=|watch\?.+&v=))((\w|-){11,})(?:\S+)?$/gmi;
|
||||
return (url.match(p)) ? RegExp.$1 : false;
|
||||
}
|
||||
|
||||
$timeout(function(){
|
||||
var iframes = element.find('iframe');
|
||||
if(iframes.length > 0)
|
||||
{
|
||||
angular.forEach(iframes, function(i) {
|
||||
|
||||
var iframe = angular.element(i),
|
||||
youtube_video_id = ((iframe.length > 0) && (!_.isUndefined(iframe[0].src))) ? ytVidId(iframe[0].src) : false;
|
||||
if(youtube_video_id !== false)
|
||||
{
|
||||
// Then it's a youtube video, compile our custom directive
|
||||
var ionic_yt_video = $compile("<ionic-youtube-video video-id='"+youtube_video_id+"'></ionic-youtube-video>")(scope);
|
||||
iframe.parent().append(ionic_yt_video);
|
||||
iframe.remove();
|
||||
}
|
||||
});
|
||||
}
|
||||
}, 10);
|
||||
}
|
||||
};
|
||||
})
|
||||
|
||||
//Use this directive to open external links using inAppBrowser cordova plugin
|
||||
.directive('dynamicAnchorFix', function($ionicGesture, $timeout, $cordovaInAppBrowser) {
|
||||
return {
|
||||
scope: {},
|
||||
link: function(scope, element, attrs) {
|
||||
$timeout(function(){
|
||||
var anchors = element.find('a');
|
||||
if(anchors.length > 0)
|
||||
{
|
||||
angular.forEach(anchors, function(a) {
|
||||
|
||||
var anchor = angular.element(a);
|
||||
|
||||
anchor.bind('click', function (event) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
var href = event.currentTarget.href;
|
||||
var options = {};
|
||||
|
||||
//inAppBrowser see documentation here: http://ngcordova.com/docs/plugins/inAppBrowser/
|
||||
|
||||
$cordovaInAppBrowser.open(href, '_blank', options)
|
||||
.then(function(e) {
|
||||
// success
|
||||
})
|
||||
.catch(function(e) {
|
||||
// error
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
}, 10);
|
||||
},
|
||||
restrict: 'A',
|
||||
replace: false,
|
||||
transclude: false
|
||||
};
|
||||
})
|
||||
|
||||
|
||||
.directive('multiBg', function(_){
|
||||
return {
|
||||
scope: {
|
||||
multiBg: '=',
|
||||
interval: '=',
|
||||
helperClass: '@'
|
||||
},
|
||||
controller: function($scope, $element, $attrs) {
|
||||
$scope.loaded = false;
|
||||
var utils = this;
|
||||
|
||||
this.animateBg = function(){
|
||||
// Think i have to use apply because this function is not called from this controller ($scope)
|
||||
$scope.$apply(function () {
|
||||
$scope.loaded = true;
|
||||
$element.css({'background-image': 'url(' + $scope.bg_img + ')'});
|
||||
});
|
||||
};
|
||||
|
||||
this.setBackground = function(bg) {
|
||||
$scope.bg_img = bg;
|
||||
};
|
||||
|
||||
if(!_.isUndefined($scope.multiBg))
|
||||
{
|
||||
if(_.isArray($scope.multiBg) && ($scope.multiBg.length > 1) && !_.isUndefined($scope.interval) && _.isNumber($scope.interval))
|
||||
{
|
||||
// Then we need to loop through the bg images
|
||||
utils.setBackground($scope.multiBg[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Then just set the multiBg image as background image
|
||||
utils.setBackground($scope.multiBg[0]);
|
||||
}
|
||||
}
|
||||
},
|
||||
templateUrl: 'views/common/multi-bg.html',
|
||||
restrict: 'A',
|
||||
replace: true,
|
||||
transclude: true
|
||||
};
|
||||
})
|
||||
|
||||
|
||||
.directive('bg', function() {
|
||||
return {
|
||||
restrict: 'A',
|
||||
require: '^multiBg',
|
||||
scope: {
|
||||
ngSrc: '@'
|
||||
},
|
||||
link: function(scope, element, attr, multiBgController) {
|
||||
element.on('load', function() {
|
||||
multiBgController.animateBg();
|
||||
});
|
||||
}
|
||||
};
|
||||
})
|
||||
|
||||
.directive('preImg', function() {
|
||||
return {
|
||||
restrict: 'E',
|
||||
transclude: true,
|
||||
scope: {
|
||||
ratio:'@',
|
||||
helperClass: '@'
|
||||
},
|
||||
controller: function($scope) {
|
||||
$scope.loaded = false;
|
||||
|
||||
this.hideSpinner = function(){
|
||||
// Think i have to use apply because this function is not called from this controller ($scope)
|
||||
$scope.$apply(function () {
|
||||
$scope.loaded = true;
|
||||
});
|
||||
};
|
||||
},
|
||||
templateUrl: 'views/common/pre-img.html'
|
||||
};
|
||||
})
|
||||
|
||||
.directive('spinnerOnLoad', function() {
|
||||
return {
|
||||
restrict: 'A',
|
||||
require: '^preImg',
|
||||
scope: {
|
||||
ngSrc: '@'
|
||||
},
|
||||
link: function(scope, element, attr, preImgController) {
|
||||
element.on('load', function() {
|
||||
preImgController.hideSpinner();
|
||||
});
|
||||
}
|
||||
};
|
||||
})
|
||||
|
||||
|
||||
;
|
||||
212
hackatonApp/www/js/factories.js
Normal file
212
hackatonApp/www/js/factories.js
Normal file
|
|
@ -0,0 +1,212 @@
|
|||
angular.module('your_app_name.factories', [])
|
||||
|
||||
.factory('FeedLoader', function ($resource){
|
||||
return $resource('http://ajax.googleapis.com/ajax/services/feed/load', {}, {
|
||||
fetch: { method: 'JSONP', params: {v: '1.0', callback: 'JSON_CALLBACK'} }
|
||||
});
|
||||
})
|
||||
|
||||
|
||||
// Factory for node-pushserver (running locally in this case), if you are using other push notifications server you need to change this
|
||||
.factory('NodePushServer', function ($http){
|
||||
// Configure push notifications server address
|
||||
// - If you are running a local push notifications server you can test this by setting the local IP (on mac run: ipconfig getifaddr en1)
|
||||
var push_server_address = "http://192.168.1.102:8000";
|
||||
|
||||
return {
|
||||
// Stores the device token in a db using node-pushserver
|
||||
// type: Platform type (ios, android etc)
|
||||
storeDeviceToken: function(type, regId) {
|
||||
// Create a random userid to store with it
|
||||
var user = {
|
||||
user: 'user' + Math.floor((Math.random() * 10000000) + 1),
|
||||
type: type,
|
||||
token: regId
|
||||
};
|
||||
console.log("Post token for registered device with data " + JSON.stringify(user));
|
||||
|
||||
$http.post(push_server_address+'/subscribe', JSON.stringify(user))
|
||||
.success(function (data, status) {
|
||||
console.log("Token stored, device is successfully subscribed to receive push notifications.");
|
||||
})
|
||||
.error(function (data, status) {
|
||||
console.log("Error storing device token." + data + " " + status);
|
||||
});
|
||||
},
|
||||
// CURRENTLY NOT USED!
|
||||
// Removes the device token from the db via node-pushserver API unsubscribe (running locally in this case).
|
||||
// If you registered the same device with different userids, *ALL* will be removed. (It's recommended to register each
|
||||
// time the app opens which this currently does. However in many cases you will always receive the same device token as
|
||||
// previously so multiple userids will be created with the same token unless you add code to check).
|
||||
removeDeviceToken: function(token) {
|
||||
var tkn = {"token": token};
|
||||
$http.post(push_server_address+'/unsubscribe', JSON.stringify(tkn))
|
||||
.success(function (data, status) {
|
||||
console.log("Token removed, device is successfully unsubscribed and will not receive push notifications.");
|
||||
})
|
||||
.error(function (data, status) {
|
||||
console.log("Error removing device token." + data + " " + status);
|
||||
});
|
||||
}
|
||||
};
|
||||
})
|
||||
|
||||
|
||||
.factory('AdMob', function ($window){
|
||||
var admob = $window.AdMob;
|
||||
|
||||
if(admob)
|
||||
{
|
||||
// Register AdMob events
|
||||
// new events, with variable to differentiate: adNetwork, adType, adEvent
|
||||
document.addEventListener('onAdFailLoad', function(data){
|
||||
console.log('error: ' + data.error +
|
||||
', reason: ' + data.reason +
|
||||
', adNetwork:' + data.adNetwork +
|
||||
', adType:' + data.adType +
|
||||
', adEvent:' + data.adEvent); // adType: 'banner' or 'interstitial'
|
||||
});
|
||||
document.addEventListener('onAdLoaded', function(data){
|
||||
console.log('onAdLoaded: ' + data);
|
||||
});
|
||||
document.addEventListener('onAdPresent', function(data){
|
||||
console.log('onAdPresent: ' + data);
|
||||
});
|
||||
document.addEventListener('onAdLeaveApp', function(data){
|
||||
console.log('onAdLeaveApp: ' + data);
|
||||
});
|
||||
document.addEventListener('onAdDismiss', function(data){
|
||||
console.log('onAdDismiss: ' + data);
|
||||
});
|
||||
|
||||
var defaultOptions = {
|
||||
// bannerId: admobid.banner,
|
||||
// interstitialId: admobid.interstitial,
|
||||
// adSize: 'SMART_BANNER',
|
||||
// width: integer, // valid when set adSize 'CUSTOM'
|
||||
// height: integer, // valid when set adSize 'CUSTOM'
|
||||
position: admob.AD_POSITION.BOTTOM_CENTER,
|
||||
// offsetTopBar: false, // avoid overlapped by status bar, for iOS7+
|
||||
bgColor: 'black', // color name, or '#RRGGBB'
|
||||
// x: integer, // valid when set position to 0 / POS_XY
|
||||
// y: integer, // valid when set position to 0 / POS_XY
|
||||
isTesting: true, // set to true, to receiving test ad for testing purpose
|
||||
// autoShow: true // auto show interstitial ad when loaded, set to false if prepare/show
|
||||
};
|
||||
var admobid = {};
|
||||
|
||||
if(ionic.Platform.isAndroid())
|
||||
{
|
||||
admobid = { // for Android
|
||||
banner: 'ca-app-pub-6869992474017983/9375997553',
|
||||
interstitial: 'ca-app-pub-6869992474017983/1657046752'
|
||||
};
|
||||
}
|
||||
|
||||
if(ionic.Platform.isIOS())
|
||||
{
|
||||
admobid = { // for iOS
|
||||
banner: 'ca-app-pub-6869992474017983/4806197152',
|
||||
interstitial: 'ca-app-pub-6869992474017983/7563979554'
|
||||
};
|
||||
}
|
||||
|
||||
admob.setOptions(defaultOptions);
|
||||
|
||||
// Prepare the ad before showing it
|
||||
// - (for example at the beginning of a game level)
|
||||
admob.prepareInterstitial({
|
||||
adId: admobid.interstitial,
|
||||
autoShow: false,
|
||||
success: function(){
|
||||
console.log('interstitial prepared');
|
||||
},
|
||||
error: function(){
|
||||
console.log('failed to prepare interstitial');
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
console.log("No AdMob?");
|
||||
}
|
||||
|
||||
return {
|
||||
showBanner: function() {
|
||||
if(admob)
|
||||
{
|
||||
admob.createBanner({
|
||||
adId:admobid.banner,
|
||||
position:admob.AD_POSITION.BOTTOM_CENTER,
|
||||
autoShow:true,
|
||||
success: function(){
|
||||
console.log('banner created');
|
||||
},
|
||||
error: function(){
|
||||
console.log('failed to create banner');
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
showInterstitial: function() {
|
||||
if(admob)
|
||||
{
|
||||
// If you didn't prepare it before, you can show it like this
|
||||
// admob.prepareInterstitial({adId:admobid.interstitial, autoShow:autoshow});
|
||||
|
||||
// If you did prepare it before, then show it like this
|
||||
// - (for example: check and show it at end of a game level)
|
||||
admob.showInterstitial();
|
||||
}
|
||||
},
|
||||
removeAds: function() {
|
||||
if(admob)
|
||||
{
|
||||
admob.removeBanner();
|
||||
}
|
||||
}
|
||||
};
|
||||
})
|
||||
|
||||
.factory('iAd', function ($window){
|
||||
var iAd = $window.iAd;
|
||||
|
||||
// preppare and load ad resource in background, e.g. at begining of game level
|
||||
if(iAd) {
|
||||
iAd.prepareInterstitial( { autoShow:false } );
|
||||
}
|
||||
else
|
||||
{
|
||||
console.log("No iAd?");
|
||||
}
|
||||
|
||||
return {
|
||||
showBanner: function() {
|
||||
if(iAd)
|
||||
{
|
||||
// show a default banner at bottom
|
||||
iAd.createBanner({
|
||||
position:iAd.AD_POSITION.BOTTOM_CENTER,
|
||||
autoShow:true
|
||||
});
|
||||
}
|
||||
},
|
||||
showInterstitial: function() {
|
||||
// ** Notice: iAd interstitial Ad only supports iPad.
|
||||
if(iAd)
|
||||
{
|
||||
// If you did prepare it before, then show it like this
|
||||
// - (for example: check and show it at end of a game level)
|
||||
iAd.showInterstitial();
|
||||
}
|
||||
},
|
||||
removeAds: function() {
|
||||
if(iAd)
|
||||
{
|
||||
iAd.removeBanner();
|
||||
}
|
||||
}
|
||||
};
|
||||
})
|
||||
|
||||
;
|
||||
15
hackatonApp/www/js/filters.js
Normal file
15
hackatonApp/www/js/filters.js
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
angular.module('your_app_name.filters', [])
|
||||
|
||||
.filter('rawHtml', function($sce){
|
||||
return function(val) {
|
||||
return $sce.trustAsHtml(val);
|
||||
};
|
||||
})
|
||||
|
||||
.filter('parseDate', function() {
|
||||
return function(value) {
|
||||
return Date.parse(value);
|
||||
};
|
||||
})
|
||||
|
||||
;
|
||||
227
hackatonApp/www/js/services.js
Normal file
227
hackatonApp/www/js/services.js
Normal file
|
|
@ -0,0 +1,227 @@
|
|||
angular.module('your_app_name.services', [])
|
||||
|
||||
.service('FeedList', function ($rootScope, FeedLoader, $q){
|
||||
this.get = function(feedSourceUrl) {
|
||||
var response = $q.defer();
|
||||
//num is the number of results to pull form the source
|
||||
FeedLoader.fetch({q: feedSourceUrl, num: 20}, {}, function (data){
|
||||
response.resolve(data.responseData);
|
||||
});
|
||||
return response.promise;
|
||||
};
|
||||
})
|
||||
|
||||
|
||||
// PUSH NOTIFICATIONS
|
||||
.service('PushNotificationsService', function ($rootScope, $cordovaPush, NodePushServer, GCM_SENDER_ID){
|
||||
/* Apple recommends you register your application for push notifications on the device every time it’s run since tokens can change. The documentation says: ‘By requesting the device token and passing it to the provider every time your application launches, you help to ensure that the provider has the current token for the device. If a user restores a backup to a device other than the one that the backup was created for (for example, the user migrates data to a new device), he or she must launch the application at least once for it to receive notifications again. If the user restores backup data to a new device or reinstalls the operating system, the device token changes. Moreover, never cache a device token and give that to your provider; always get the token from the system whenever you need it.’ */
|
||||
this.register = function() {
|
||||
var config = {};
|
||||
|
||||
// ANDROID PUSH NOTIFICATIONS
|
||||
if(ionic.Platform.isAndroid())
|
||||
{
|
||||
config = {
|
||||
"senderID": GCM_SENDER_ID
|
||||
};
|
||||
|
||||
$cordovaPush.register(config).then(function(result) {
|
||||
// Success
|
||||
console.log("$cordovaPush.register Success");
|
||||
console.log(result);
|
||||
}, function(err) {
|
||||
// Error
|
||||
console.log("$cordovaPush.register Error");
|
||||
console.log(err);
|
||||
});
|
||||
|
||||
$rootScope.$on('$cordovaPush:notificationReceived', function(event, notification) {
|
||||
console.log(JSON.stringify([notification]));
|
||||
switch(notification.event)
|
||||
{
|
||||
case 'registered':
|
||||
if (notification.regid.length > 0 ) {
|
||||
console.log('registration ID = ' + notification.regid);
|
||||
NodePushServer.storeDeviceToken("android", notification.regid);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'message':
|
||||
if(notification.foreground == "1")
|
||||
{
|
||||
console.log("Notification received when app was opened (foreground = true)");
|
||||
}
|
||||
else
|
||||
{
|
||||
if(notification.coldstart == "1")
|
||||
{
|
||||
console.log("Notification received when app was closed (not even in background, foreground = false, coldstart = true)");
|
||||
}
|
||||
else
|
||||
{
|
||||
console.log("Notification received when app was in background (started but not focused, foreground = false, coldstart = false)");
|
||||
}
|
||||
}
|
||||
|
||||
// this is the actual push notification. its format depends on the data model from the push server
|
||||
console.log('message = ' + notification.message);
|
||||
break;
|
||||
|
||||
case 'error':
|
||||
console.log('GCM error = ' + notification.msg);
|
||||
break;
|
||||
|
||||
default:
|
||||
console.log('An unknown GCM event has occurred');
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
// WARNING: dangerous to unregister (results in loss of tokenID)
|
||||
// $cordovaPush.unregister(options).then(function(result) {
|
||||
// // Success!
|
||||
// }, function(err) {
|
||||
// // Error
|
||||
// });
|
||||
}
|
||||
|
||||
if(ionic.Platform.isIOS())
|
||||
{
|
||||
config = {
|
||||
"badge": true,
|
||||
"sound": true,
|
||||
"alert": true
|
||||
};
|
||||
|
||||
$cordovaPush.register(config).then(function(result) {
|
||||
// Success -- send deviceToken to server, and store for future use
|
||||
console.log("result: " + result);
|
||||
NodePushServer.storeDeviceToken("ios", result);
|
||||
}, function(err) {
|
||||
console.log("Registration error: " + err);
|
||||
});
|
||||
|
||||
$rootScope.$on('$cordovaPush:notificationReceived', function(event, notification) {
|
||||
console.log(notification.alert, "Push Notification Received");
|
||||
});
|
||||
}
|
||||
};
|
||||
})
|
||||
|
||||
|
||||
// BOOKMARKS FUNCTIONS
|
||||
.service('BookMarkService', function (_, $rootScope){
|
||||
|
||||
this.bookmarkFeedPost = function(bookmark_post){
|
||||
|
||||
var user_bookmarks = !_.isUndefined(window.localStorage.ionFullApp_feed_bookmarks) ?
|
||||
JSON.parse(window.localStorage.ionFullApp_feed_bookmarks) : [];
|
||||
|
||||
//check if this post is already saved
|
||||
|
||||
var existing_post = _.find(user_bookmarks, function(post){ return post.link == bookmark_post.link; });
|
||||
|
||||
if(!existing_post){
|
||||
user_bookmarks.push({
|
||||
link: bookmark_post.link,
|
||||
title : bookmark_post.title,
|
||||
date: bookmark_post.publishedDate,
|
||||
excerpt: bookmark_post.contentSnippet
|
||||
});
|
||||
}
|
||||
|
||||
window.localStorage.ionFullApp_feed_bookmarks = JSON.stringify(user_bookmarks);
|
||||
$rootScope.$broadcast("new-bookmark");
|
||||
};
|
||||
|
||||
this.bookmarkWordpressPost = function(bookmark_post){
|
||||
|
||||
var user_bookmarks = !_.isUndefined(window.localStorage.ionFullApp_wordpress_bookmarks) ?
|
||||
JSON.parse(window.localStorage.ionFullApp_wordpress_bookmarks) : [];
|
||||
|
||||
//check if this post is already saved
|
||||
|
||||
var existing_post = _.find(user_bookmarks, function(post){ return post.id == bookmark_post.id; });
|
||||
|
||||
if(!existing_post){
|
||||
user_bookmarks.push({
|
||||
id: bookmark_post.id,
|
||||
title : bookmark_post.title,
|
||||
date: bookmark_post.date,
|
||||
excerpt: bookmark_post.excerpt
|
||||
});
|
||||
}
|
||||
|
||||
window.localStorage.ionFullApp_wordpress_bookmarks = JSON.stringify(user_bookmarks);
|
||||
$rootScope.$broadcast("new-bookmark");
|
||||
};
|
||||
|
||||
this.getBookmarks = function(){
|
||||
return {
|
||||
feeds : JSON.parse(window.localStorage.ionFullApp_feed_bookmarks || '[]'),
|
||||
wordpress: JSON.parse(window.localStorage.ionFullApp_wordpress_bookmarks || '[]')
|
||||
};
|
||||
};
|
||||
})
|
||||
|
||||
|
||||
// WP POSTS RELATED FUNCTIONS
|
||||
.service('PostService', function ($rootScope, $http, $q, WORDPRESS_API_URL){
|
||||
|
||||
this.getRecentPosts = function(page) {
|
||||
var deferred = $q.defer();
|
||||
|
||||
$http.jsonp(WORDPRESS_API_URL + 'get_recent_posts/' +
|
||||
'?page='+ page +
|
||||
'&callback=JSON_CALLBACK')
|
||||
.success(function(data) {
|
||||
deferred.resolve(data);
|
||||
})
|
||||
.error(function(data) {
|
||||
deferred.reject(data);
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
|
||||
this.getPost = function(postId) {
|
||||
var deferred = $q.defer();
|
||||
|
||||
$http.jsonp(WORDPRESS_API_URL + 'get_post/' +
|
||||
'?post_id='+ postId +
|
||||
'&callback=JSON_CALLBACK')
|
||||
.success(function(data) {
|
||||
deferred.resolve(data);
|
||||
})
|
||||
.error(function(data) {
|
||||
deferred.reject(data);
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
this.shortenPosts = function(posts) {
|
||||
//we will shorten the post
|
||||
//define the max length (characters) of your post content
|
||||
var maxLength = 500;
|
||||
return _.map(posts, function(post){
|
||||
if(post.content.length > maxLength){
|
||||
//trim the string to the maximum length
|
||||
var trimmedString = post.content.substr(0, maxLength);
|
||||
//re-trim if we are in the middle of a word
|
||||
trimmedString = trimmedString.substr(0, Math.min(trimmedString.length, trimmedString.lastIndexOf("</p>")));
|
||||
post.content = trimmedString;
|
||||
}
|
||||
return post;
|
||||
});
|
||||
};
|
||||
|
||||
this.sharePost = function(link){
|
||||
window.plugins.socialsharing.share('Check this post here: ', null, null, link);
|
||||
};
|
||||
|
||||
})
|
||||
|
||||
|
||||
;
|
||||
Loading…
Add table
Add a link
Reference in a new issue