First Commit

This commit is contained in:
Lorenzo Iovino 2016-01-29 13:14:27 +01:00
commit feb864dc47
170 changed files with 4671 additions and 0 deletions

View file

@ -0,0 +1,191 @@
[
{
"id":"news",
"title":"News",
"image":"img/feeds/news.jpg",
"feed_sources":[
{
"id":"bbc",
"title":"BBC",
"description":"The latest stories from the World section of the BBC News web site.",
"image":"img/feeds/logos/bbc.jpg",
"url":"http://feeds.bbci.co.uk/news/world/rss.xml"
},
{
"id":"reuters",
"title":"Reuters",
"description":"Reuters.com is your source for breaking news, business, financial and investing news, including personal finance and stocks. Reuters is the leading global provider of news, financial information and technology solutions to the world's media, financial institutions, businesses and individuals.",
"image":"img/feeds/logos/reuters.jpg",
"url":"http://feeds.reuters.com/Reuters/worldNews"
},
{
"id":"cnn",
"title":"CNN",
"description":"CNN.com delivers up-to-the-minute news and information on the latest top stories, weather, entertainment, politics and more.",
"image":"img/feeds/logos/cnn.jpg",
"url":"http://rss.cnn.com/rss/cnn_world.rss"
},
{
"id":"the-guardian",
"title":"The Guardian",
"description":"Latest World news, comment and analysis from the Guardian, the world's leading liberal voice",
"image":"img/feeds/logos/the-guardian.jpg",
"url":"http://www.theguardian.com/world/rss"
}
]
},
{
"id":"sports",
"title":"Sports",
"image":"img/feeds/sports.jpg",
"feed_sources":[
{
"id":"the-guardian",
"title":"The Guardian",
"description":"Latest news and features from theguardian.com, the world's leading liberal voice",
"image":"img/feeds/logos/the-guardian.jpg",
"url":"http://www.theguardian.com/sport/rss"
},
{
"id":"bbc",
"title":"BBC",
"description":"The latest stories from the Sport section of the BBC Sport web site.",
"image":"img/feeds/logos/bbc.jpg",
"url":"http://feeds.bbci.co.uk/sport/0/rss.xml"
},
{
"id":"fox-sports",
"title":"FOX Sports",
"description":"FOX Sports Generic Content Feed",
"image":"img/feeds/logos/fox-sports.jpg",
"url":"http://api.foxsports.com/v1/rss?partnerKey=zBaFxRyGKCfxBagJG9b8pqLyndmvo7UU"
},
{
"id":"espn",
"title":"ESPN",
"description":"Latest news from ESPN.com",
"image":"img/feeds/logos/espn.jpg",
"url":"http://sports.espn.go.com/espn/rss/news"
}
]
},
{
"id":"business",
"title":"Business",
"image":"img/feeds/business.jpg",
"feed_sources":[
{
"id":"forbes",
"title":"Forbes",
"description":"Forbes - Business",
"image":"img/feeds/logos/forbes.jpg",
"url":"http://www.forbes.com/business/feed/"
},
{
"id":"reuters",
"title":"Reuters",
"description":"Reuters.com is your source for breaking news, business, financial and investing news, including personal finance and stocks. Reuters is the leading global provider of news, financial information and technology solutions to the world's media, financial institutions, businesses and individuals.",
"image":"img/feeds/logos/reuters.jpg",
"url":"http://feeds.reuters.com/reuters/businessNews"
},
{
"id":"the-economist",
"title":"The Economist",
"description":"The Economist business and finance",
"image":"img/feeds/logos/the-economist.jpg",
"url":"http://www.economist.com/sections/business-finance/rss.xml"
},
{
"id":"inc",
"title":"Inc.",
"description":"Advice for founders of start-ups and start-up entrepreneurs on writing a business plan, running a home-based business, naming a start-up business, how to incorporate, financing a start-up, buying a small business, and starting a franchise.",
"image":"img/feeds/logos/inc.jpg",
"url":"http://feeds.feedburner.com/inc/channel/start-up"
}
]
},
{
"id":"entertainment",
"title":"Entertainment",
"image":"img/feeds/entertainment.jpg",
"feed_sources":[
{
"id":"the-hollywood-reporter",
"title":"The Hollywood Reporter",
"description":"The Hollywood Reporter news",
"image":"img/feeds/logos/the-hollywood-reporter.jpg",
"url":"http://feeds.feedburner.com/thr/news"
},
{
"id":"tmz",
"title":"TMZ",
"description":"Celebrity Gossip and Entertainment News, Covering Celebrity News and Hollywood Rumors. Get All The Latest Gossip at TMZ - Thirty Mile Zone.",
"image":"img/feeds/logos/tmz.jpg",
"url":"http://www.tmz.com/rss.xml"
},
{
"id":"the-guardian",
"title":"The Guardian",
"description":"Latest news and features from theguardian.com, the world's leading liberal voice",
"image":"img/feeds/logos/the-guardian.jpg",
"url":"http://www.theguardian.com/culture/rss"
}
]
},
{
"id":"politics",
"title":"Politics",
"image":"img/feeds/politics.jpg",
"feed_sources":[
{
"id":"the-nation",
"title":"The Nation",
"description":"The Nation politics news",
"image":"img/feeds/logos/the-nation.jpg",
"url":"http://www.thenation.com/blogs/rss/politics"
},
{
"id":"washington-post",
"title":"Washington Post",
"description":"Post Politics from The Washington Post is the source for political news headlines, in-depth politics coverage and political opinion, plus breaking news on the Obama administration and White House, Congress, the Supreme Court, elections and more.",
"image":"img/feeds/logos/washington-post.jpg",
"url":"http://feeds.washingtonpost.com/rss/politics"
},
{
"id":"reuters",
"title":"Reuters",
"description":"Reuters.com is your source for breaking news, business, financial and investing news, including personal finance and stocks. Reuters is the leading global provider of news, financial information and technology solutions to the world's media, financial institutions, businesses and individuals.",
"image":"img/feeds/logos/reuters.jpg",
"url":"http://feeds.reuters.com/Reuters/PoliticsNews"
}
]
},
{
"id":"technology",
"title":"Technology",
"image":"img/feeds/technology.jpg",
"feed_sources":[
{
"id":"techcrunch",
"title":"TechCrunch",
"description":"Startup and Technology News",
"image":"img/feeds/logos/techcrunch.jpg",
"url":"http://feeds.feedburner.com/TechCrunch/social"
},
{
"id":"techradar",
"title":"Techradar",
"description":"Get all the latest tech news from Techradar.com",
"image":"img/feeds/logos/techradar.jpg",
"url":"http://feeds2.feedburner.com/techradar/allnews"
},
{
"id":"cnet",
"title":"CNET",
"description":"CNET news editors and reporters provide top technology news, with investigative reporting and in-depth coverage of tech issues and events",
"image":"img/feeds/logos/cnet.jpg",
"url":"http://www.cnet.com/rss/news/"
}
]
}
]

Binary file not shown.

After

Width:  |  Height:  |  Size: 564 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

View file

@ -0,0 +1,40 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
<meta http-equiv="Content-Security-Policy" content="default-src *; script-src &apos;self&apos; &apos;unsafe-inline&apos; &apos;unsafe-eval&apos; *; style-src &apos;self&apos; &apos;unsafe-inline&apos; *">
<title></title>
<link href="css/ionic.app.css" rel="stylesheet">
<link href="lib/ionic-contrib-tinder-cards/ionic.tdcards.css" rel="stylesheet">
<script src="https://maps.google.com/maps/api/js"></script>
<script src="https://www.youtube.com/iframe_api"></script>
<script src="lib/ionic/js/ionic.bundle.js"></script>
<script src="lib/angular-resource/angular-resource.min.js"></script>
<script src="lib/underscore/underscore-min.js"></script>
<script src="lib/ngmap/build/scripts/ng-map.min.js"></script>
<script src="lib/ngCordova/dist/ng-cordova.min.js"></script>
<script src="lib/moment/min/moment.min.js"></script>
<script src="lib/angular-moment/angular-moment.min.js"></script>
<script src="lib/angular-slugify/dist/angular-slugify.min.js"></script>
<script src="lib/collide/collide.js"></script>
<script src="lib/ionic-contrib-tinder-cards/ionic.tdcards.js"></script>
<script src="lib/ngCordova/dist/ng-cordova.min.js"></script>
<script src="lib/angular-youtube-mb/dist/angular-youtube-embed.min.js"></script>
<!-- cordova script (this will be a 404 during development) -->
<script src="cordova.js"></script>
<script src="js/app.js"></script>
<script src="js/controllers.js"></script>
<script src="js/directives.js"></script>
<script src="js/filters.js"></script>
<script src="js/services.js"></script>
<script src="js/factories.js"></script>
<script src="js/views.js"></script>
<script src="js/config.js"></script>
</head>
<body ng-app="your_app_name">
<ion-nav-view></ion-nav-view>
</body>
</html>

283
hackatonApp/www/js/app.js Normal file
View 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');
});

View 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')
;

View 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 users 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);
};
})
;

View 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();
});
}
};
})
;

View 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();
}
}
};
})
;

View 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);
};
})
;

View 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 its 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);
};
})
;

View file

@ -0,0 +1,35 @@
<ion-view class="bookmarks-view">
<ion-nav-title>
<span>Bookmarks</span>
</ion-nav-title>
<ion-content>
<div ng-if="(bookmarks.wordpress.length == 0 && bookmarks.feeds.length == 0)" class="row bookmarks-container">
<div class="col col-center">
<div class="empty-results">
<i class="icon ion-bookmark"></i>
<h3 class="no-bookmarks">There's nothing here yet. Start exploring!</h3>
</div>
</div>
</div>
<ul ng-if="(bookmarks.wordpress.length > 0 || bookmarks.feeds.length > 0)" class="bookmarks-list">
<div ng-if="bookmarks.feeds.length > 0" class="item item-divider">
Feeds Bookmarks
</div>
<li class="bookmark-item" ng-repeat="bookmark in bookmarks.feeds">
<a ng-click=goToFeedPost(bookmark.link)>
<h2 class="post-title" ng-bind-html="bookmark.title | rawHtml"></h2>
<p class="post-date">Posted <span class="post-time" am-time-ago="bookmark.date"></span></p>
</a>
</li>
<div ng-if="bookmarks.wordpress.length > 0" class="item item-divider">
Wordpress bookmarks
</div>
<li class="bookmark-item" ng-repeat="bookmark in bookmarks.wordpress">
<a ng-click=goToWordpressPost(bookmark.id)>
<h2 class="post-title" ng-bind-html="bookmark.title | rawHtml"></h2>
<p class="post-date">Posted <span class="post-time" am-time-ago="bookmark.date"></span></p>
</a>
</li>
</ul>
</ion-content>
</ion-view>

View file

@ -0,0 +1,21 @@
<ion-view class="category-feeds-view">
<ion-nav-title>
<span>{{categoryTitle}} feeds</span>
</ion-nav-title>
<ion-content>
<div class="list category-feeds">
<a ng-repeat="source in category_sources" class="item item-icon-right" ui-sref="app.feed-entries({categoryId: categoryId, sourceId: (source.title | slugify)})">
<div class="thumbnail-outer">
<pre-img ratio="_1_1" helper-class="">
<img class="thumbnail" ng-src="{{source.image}}" spinner-on-load>
</pre-img>
</div>
<div>
<span class="title">{{source.title}}</span>
<p class="description">{{source.description}}</p>
</div>
<i class="icon ion-arrow-right-c"></i>
</a>
</div>
</ion-content>
</ion-view>

View file

@ -0,0 +1,34 @@
<ion-view class="feed-entries-view">
<ion-nav-title>
<span>{{sourceTitle}}</span>
</ion-nav-title>
<ion-content>
<!-- Refresh to get the new posts -->
<ion-refresher pulling-text="Pull to refresh..." on-refresh="doRefresh()">
</ion-refresher>
<div class="entries-list">
<div ng-repeat="entry in feed.entries" class="list card entry-item">
<div class="entry-heading item item-text-wrap">
<h2 class="entry-title" ng-bind-html="entry.title | rawHtml"></h2>
<p class="entry-author">
Published <span>{{ entry.publishedDate | parseDate | amTimeAgo }}</span>
</p>
</div>
<div class="entry-content item item-text-wrap">
<p class="entry-excerpt" dynamic-anchor-fix ng-bind-html="entry.contentSnippet | rawHtml"></p>
<div class="entry-actions row">
<div class="actions col col-center col-66">
<a class="button button-icon icon ion-bookmark" ng-click="bookmarkPost(entry)"></a>
</div>
<div class="read-more col col-center col-33" dynamic-anchor-fix>
<a class="button button-small button-block button-assertive" ng-href="{{entry.link}}">
Read more
</a>
</div>
</div>
</div>
</div>
</div>
</ion-content>
</ion-view>

View file

@ -0,0 +1,21 @@
<ion-view class="feeds-categories-view">
<ion-nav-buttons side="left">
<button menu-toggle="left" class="button button-icon icon ion-navicon"></button>
</ion-nav-buttons>
<ion-nav-title>
<span>Feeds Categories</span>
</ion-nav-title>
<ion-content>
<div class="row categories-list">
<div ng-repeat="category in feeds_categories" class="col col-50">
<a class="feed-category" ui-sref="app.category-feeds({categoryId: (category.title | slugify)})">
<pre-img ratio="_1_1" helper-class="square-image">
<img class="category-image" ng-src="{{category.image}}" spinner-on-load>
</pre-img>
<div class="category-bg"></div>
<span class="category-title">{{category.title}}</span>
</a>
</div>
</div>
</ion-content>
</ion-view>

View file

@ -0,0 +1,69 @@
<ion-view class="forms-view">
<ion-nav-buttons side="left">
<button menu-toggle="left" class="button button-icon icon ion-navicon"></button>
</ion-nav-buttons>
<ion-nav-title>
<span>Forms</span>
</ion-nav-title>
<ion-content>
<ul class="list">
<div class="item item-divider">Inline Labels</div>
<label class="item item-input">
<span class="input-label">First Name</span>
<input type="text">
</label>
<label class="item item-input">
<span class="input-label">Last Name</span>
<input type="text">
</label>
<label class="item item-input">
<span class="input-label">Email</span>
<input type="email">
</label>
<div class="item item-divider">Floating Labels</div>
<label class="item item-input item-floating-label">
<span class="input-label">Telephone</span>
<input type="tel" placeholder="Your phone">
</label>
<label class="item item-input item-floating-label">
<span class="input-label">Number</span>
<input type="number" placeholder="Some number">
</label>
<div class="item item-divider">Stacked Labels</div>
<label class="item item-input item-stacked-label">
<span class="input-label">Birth date</span>
<input type="date">
</label>
<label class="item item-input item-stacked-label">
<span class="input-label">Month</span>
<input type="month">
</label>
<div class="item item-divider">Placeholder Labels</div>
<label class="item item-input">
<textarea placeholder="Description"></textarea>
</label>
<label class="item item-input">
<input type="password" placeholder="Your password">
</label>
<div class="item item-divider">Inset Inputs</div>
<div class="item item-input-inset">
<label class="item-input-wrapper">
<input type="text" placeholder="Search...">
</label>
<button class="button button-small">
Submit
</button>
</div>
</ul>
</ion-content>
</ion-view>

View file

@ -0,0 +1,28 @@
<ion-view class="layouts-view">
<ion-nav-buttons side="left">
<button menu-toggle="left" class="button button-icon icon ion-navicon"></button>
</ion-nav-buttons>
<ion-nav-title>
<span>Layouts</span>
</ion-nav-title>
<ion-content>
<div class="list layouts-functionalities">
<a class="item item-icon-left item-icon-right" ui-sref="app.tinder-cards">
<i class="icon ion-happy-outline"></i>
<div>
<span class="title">Tinder Cards</span>
<p class="description">Awesome Tinder Cards</p>
</div>
<i class="icon ion-arrow-right-c"></i>
</a>
<a class="item item-icon-left item-icon-right" ui-sref="app.slider">
<i class="icon ion-arrow-swap"></i>
<div>
<span class="title">Slider</span>
<p class="description">Example of sliding cards</p>
</div>
<i class="icon ion-arrow-right-c"></i>
</a>
</div>
</ion-content>
</ion-view>

View file

@ -0,0 +1,19 @@
<ion-view class="slider-view">
<ion-nav-title>
<span>Slider</span>
</ion-nav-title>
<ion-content scroll="false">
<ion-slide-box show-pager="true">
<ion-slide ng-repeat="i in [1,2,3,4,5]">
<div class="list card">
<div class="item item-image">
<img ng-src="http://lorempixel.com/300/200/nature?v={{i}}">
</div>
<div class="item item-body">
<p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.</p>
</div>
</div>
</ion-slide>
</ion-slide-box>
</ion-content>
</ion-view>

View file

@ -0,0 +1,34 @@
<ion-view class="tinder-cards-view">
<ion-nav-title>
<span>Tinder Cards</span>
</ion-nav-title>
<ion-content scroll="false">
<td-cards>
<td-card id="td-card" ng-repeat="card in cards"
on-transition-left="transitionLeft(card)"
on-transition-right="transitionRight(card)"
on-transition-out="transitionOut(card)"
on-destroy="cardDestroyed($index)"
on-swipe-left="cardSwipedLeft($index)"
on-swipe-right="cardSwipedRight($index)"
on-partial-swipe="cardPartialSwipe(amt)">
<div class="image">
<div class="no-text overlayBox">
<div class="noBox boxed">
Nope
</div>
</div>
<img ng-src="{{card.image}}">
<div class="yes-text overlayBox">
<div class="yesBox boxed">
Yes
</div>
</div>
</div>
<div class="title">
{{card.name}}
</div>
</td-card>
</td-cards>
</ion-content>
</ion-view>

View file

@ -0,0 +1,28 @@
<ion-view class="image-picker-view">
<ion-nav-title>
<span>Image picker</span>
</ion-nav-title>
<ion-content class="padding">
<button class="button button-block button-dark" ng-click="selImages()">
Select Images
</button>
<button ng-show="images.length > 0" class="button button-block button-stable" ng-click="shareAll()">
Share All
</button>
<div class="list card" ng-repeat="img in images">
<div class="item item-image">
<img ng-src="{{img}}">
</div>
<div class="item tabs tabs-secondary tabs-icon-left">
<a class="tab-item image-option" href="#" ng-click="shareImage(img)">
<i class="icon ion-share"></i>
Share
</a>
<a class="tab-item assertive image-option" href="#" ng-click="removeImage(img)">
<i class="icon ion-trash-a assertive"></i>
Remove
</a>
</div>
</div>
</ion-content>
</ion-view>

View file

@ -0,0 +1,38 @@
<ion-view class="maps-view">
<ion-nav-title>
<span>Maps</span>
</ion-nav-title>
<ion-content scroll="false">
<div class="mapWrap" data-tap-disabled="true">
<div class="row center-map-action">
<div class="col">
<div class="list">
<div class="item item-input-inset">
<a class="button button-icon icon ion-pinpoint" ng-click="centerOnMe()"></a>
<label class="item-input-wrapper">
<input type="text" placeholder="My Location" disabled ng-model="my_location">
</label>
</div>
</div>
</div>
</div>
<map center="{{center_position.lat}},{{center_position.lng}}" zoom="15">
<marker
position="{{current_position.lat}},{{current_position.lng}}"
title="Hello Marker"
visible="true">
</marker>
<info-window id="1" position="{{info_position.lat}},{{info_position.lng}}" visible="true">
<div ng-non-bindable="">
<b>The best restaurant</b><br>
This is html so you can put whatever <br>
you want such as images and <a href="">links</a> <br>
<img style=" border-radius: 24px;" src="http://lorempixel.com/50/50/food/?v=1"></img>
<img style=" border-radius: 24px;" src="http://lorempixel.com/50/50/food/?v=2"></img>
<img style=" border-radius: 24px;" src="http://lorempixel.com/50/50/food/?v=3"></img>
</div>
</info-window>
</map>
</div>
</ion-content>
</ion-view>

View file

@ -0,0 +1,66 @@
<ion-view class="miscellaneous-view">
<ion-nav-buttons side="left">
<button menu-toggle="left" class="button button-icon icon ion-navicon"></button>
</ion-nav-buttons>
<ion-nav-title>
<span>Miscellaneous</span>
</ion-nav-title>
<ion-content>
<div class="list miscellaneous-functionalities">
<div dynamic-anchor-fix>
<a class="item item-icon-left item-icon-right" href="http://www.ionicthemes.com">
<i class="icon ion-ios-browsers-outline"></i>
<div>
<span class="title">In App Browser</span>
<p class="description">Show web browser view with external links</p>
</div>
<i class="icon ion-arrow-right-c"></i>
</a>
</div>
<a class="item item-icon-left item-icon-right" ui-sref="app.maps">
<i class="icon ion-map"></i>
<div>
<span class="title">Maps & GeoLocation</span>
<p class="description">Show map & access user's current location</p>
</div>
<i class="icon ion-arrow-right-c"></i>
</a>
<a class="item item-icon-left item-icon-right" ui-sref="app.image-picker">
<i class="icon ion-images"></i>
<div>
<span class="title">Image Picker</span>
<p class="description">Select and share images from your phone</p>
</div>
<i class="icon ion-arrow-right-c"></i>
</a>
<a class="item item-icon-left item-icon-right" href="#" ng-controller="AdsCtrl" ng-click="manageAdMob()">
<i class="icon ion-social-usd-outline"></i>
<div>
<span class="title">AdMob</span>
<p class="description">Show Google AdMob mobile ads</p>
</div>
</a>
<a class="item item-icon-left item-icon-right" href="#" ng-controller="AdsCtrl" ng-click="manageiAd()">
<i class="icon ion-social-usd-outline"></i>
<div>
<span class="title">iAd</span>
<p class="description">Show Apple iAd mobile ads</p>
</div>
</a>
<a class="item item-icon-left item-icon-right" href="#" ng-controller="RateApp" ng-click="rateApp()">
<i class="icon ion-ios-star-half"></i>
<div>
<span class="title">Rate the app</span>
<p class="description">Rate this app in Google and Apple stores</p>
</div>
</a>
<a class="item item-icon-left item-icon-right" href="#" ng-controller="SendMailCtrl" ng-click="sendMail()">
<i class="icon ion-email"></i>
<div>
<span class="title">Send email</span>
<p class="description">Access your phone native email sender provider</p>
</div>
</a>
</div>
</ion-content>
</ion-view>

View file

@ -0,0 +1,26 @@
<ion-view class="profile-view">
<ion-nav-title>
<span>Profile</span>
</ion-nav-title>
<ion-content>
<div class="top-content row">
<div class="profile-container">
<div class="user-image-container">
<pre-img ratio="_1_1" helper-class="rounded-image">
<img class="user-image" ng-src="https://s3.amazonaws.com/uifaces/faces/twitter/brynn/128.jpg" spinner-on-load>
</pre-img>
</div>
<div class="user-name">Brynn Evans</div>
<div class="user-twitter">@brynn</div>
</div>
<div class="user-background-image-outer">
<div multi-bg="['https://s3.amazonaws.com/uifaces/faces/twitter/brynn/128.jpg']"></div>
</div>
</div>
<div class="bottom-content">
<div class="user-bio">
<p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged.</p>
</div>
</div>
</ion-content>
</ion-view>

View file

@ -0,0 +1,50 @@
<ion-view class="settings-view">
<ion-nav-buttons side="left">
<button menu-toggle="left" class="button button-icon icon ion-navicon"></button>
</ion-nav-buttons>
<ion-nav-title>
<span>Settings</span>
</ion-nav-title>
<ion-content>
<ul class="list">
<div class="item item-divider">TOGGLE</div>
<ion-toggle ng-model="airplaneMode" toggle-class="toggle-assertive">Airplane Mode</ion-toggle>
<ion-toggle ng-model="wifi" toggle-class="toggle-positive">Wi-Fi</ion-toggle>
<ion-toggle ng-model="bluetooth" toggle-class="toggle-calm">Bluetooth</ion-toggle>
<ion-toggle ng-model="personalHotspot" toggle-class="toggle-dark">Personal Hotspot</ion-toggle>
<div class="item item-divider">CHECKBOXES</div>
<ion-checkbox ng-model="checkOpt1">Option 1</ion-checkbox>
<ion-checkbox ng-model="checkOpt2">Option 2</ion-checkbox>
<ion-checkbox ng-model="checkOpt3">Option 3</ion-checkbox>
<div class="item item-divider">RADIO</div>
<ion-radio ng-model="radioChoice" ng-value="'A'">Choose A</ion-radio>
<ion-radio ng-model="radioChoice" ng-value="'B'">Choose B</ion-radio>
<ion-radio ng-model="radioChoice" ng-value="'C'">Choose C</ion-radio>
<div class="item item-divider">RANGES</div>
<div class="range">
<i class="icon ion-volume-low"></i>
<input type="range" name="volume">
<i class="icon ion-volume-high"></i>
</div>
<div class="item range range-positive">
<i class="icon ion-ios-sunny-outline"></i>
<input type="range" name="volume" min="0" max="100" value="33">
<i class="icon ion-ios-sunny"></i>
</div>
<div class="item item-divider"></div>
<button class="button button-block button-assertive" ng-click="showLogOutMenu()">
Logout
</button>
</ul>
</ion-content>
</ion-view>

View file

@ -0,0 +1,58 @@
<ion-side-menus enable-menu-with-back-views="false">
<ion-side-menu-content class="post-size-14px">
<ion-nav-bar class="bar app-top-bar">
<ion-nav-back-button>
</ion-nav-back-button>
<ion-nav-buttons side="left">
<button class="button button-icon button-clear ion-navicon" menu-toggle="left">
</button>
</ion-nav-buttons>
</ion-nav-bar>
<ion-nav-view name="menuContent"></ion-nav-view>
</ion-side-menu-content>
<ion-side-menu side="left" class="main-menu" expose-aside-when="large">
<ion-content>
<ion-list>
<ion-item class="heading-item item item-avatar" nav-clear menu-close ui-sref="app.profile">
<div class="user-image-container">
<pre-img ratio="_1_1" helper-class="rounded-image">
<img class="user-image" ng-src="https://s3.amazonaws.com/uifaces/faces/twitter/brynn/128.jpg" spinner-on-load>
</pre-img>
</div>
<h2 class="greeting">Hi Brynn</h2>
<p class="message">Welcome back</p>
</ion-item>
<ion-item class="item-icon-left" nav-clear menu-close ui-sref="app.bookmarks">
<i class="icon ion-bookmark"></i>
<h2 class="menu-text">Saved for later</h2>
</ion-item>
<ion-item class="item-icon-left" nav-clear menu-close ui-sref="app.feeds-categories">
<i class="icon ion-radio-waves"></i>
<h2 class="menu-text">Feeds</h2>
</ion-item>
<ion-item class="item-icon-left" nav-clear menu-close ui-sref="app.wordpress">
<i class="icon ion-social-wordpress"></i>
<h2 class="menu-text">Wordpress</h2>
</ion-item>
<ion-item class="item-icon-left" nav-clear menu-close ui-sref="app.layouts">
<i class="icon ion-wand"></i>
<h2 class="menu-text">Layouts</h2>
</ion-item>
<ion-item class="item-icon-left" nav-clear menu-close ui-sref="app.miscellaneous">
<i class="icon ion-asterisk"></i>
<h2 class="menu-text">Miscellaneous</h2>
</ion-item>
<ion-item class="item-icon-left" nav-clear menu-close ui-sref="app.forms">
<i class="icon ion-document"></i>
<h2 class="menu-text">Forms</h2>
</ion-item>
<ion-item class="item-icon-left" nav-clear menu-close ui-sref="app.settings">
<i class="icon ion-gear-a"></i>
<h2 class="menu-text">Settings</h2>
</ion-item>
</ion-list>
</ion-content>
</ion-side-menu>
</ion-side-menus>

View file

@ -0,0 +1,41 @@
<ion-view class="wordpress-view">
<ion-nav-buttons side="left">
<button menu-toggle="left" class="button button-icon icon ion-navicon"></button>
</ion-nav-buttons>
<ion-nav-title>
<span>WordPress</span>
</ion-nav-title>
<ion-content>
<!-- Refresh to get the new posts -->
<ion-refresher pulling-text="Pull to refresh..." on-refresh="doRefresh()">
</ion-refresher>
<div class="posts-list">
<div ng-repeat="post in posts" class="list card post-item">
<div class="post-heading item item-text-wrap">
<h2 class="post-title" ng-bind-html="post.title | rawHtml"></h2>
<p class="post-author">
By <span>{{post.author.nickname}}</span> <span am-time-ago="post.date"></span>
</p>
</div>
<div class="post-content item item-text-wrap" post-content>
<p class="post-excerpt" dynamic-anchor-fix ng-bind-html="post.content | rawHtml"></p>
<div class="post-actions row">
<div class="actions col col-center col-66">
<a class="button button-icon icon ion-bookmark" ng-click="bookmarkPost(post)"></a>
</div>
<div class="read-more col col-center col-33">
<a ui-sref="app.post({postId: post.id})" class="button button-small button-block button-assertive">
Read more
</a>
</div>
</div>
</div>
</div>
</div>
<!-- Infinit scroll -->
<ion-infinite-scroll ng-if="moreDataCanBeLoaded()" on-infinite="loadMoreData()" distance="1%" icon="ion-loading-c">
</ion-infinite-scroll>
</ion-content>
</ion-view>

View file

@ -0,0 +1,32 @@
<ion-view class="post-view">
<ion-content>
<div class="post-heading item item-text-wrap">
<h1 class="post-title">{{post.title}}</h1>
<p class="post-author">
By <span>{{post.author.nickname}}</span> <span am-time-ago="post.date"></span>
</p>
</div>
<div class="post-content item item-text-wrap" post-content>
<p class="post-text" dynamic-anchor-fix ng-bind-html="post.content | rawHtml"></p>
</div>
<div class="post-tags item item-text-wrap">
<span class="post-tag button button-small button-outline button-stable" ng-repeat="category in post.categories">{{category.title}}</span>
</div>
</ion-content>
<ion-footer-bar class="post-footer bar bar-footer bar-dark">
<div class="row">
<div class="col col-20 col-center">
<a class="button button-icon icon icon-right ion-plus" bigger-text=".post-view .post-text">A</a>
</div>
<div class="col col-20 col-center">
<a class="button button-icon icon icon-right ion-minus" smaller-text=".post-view .post-text">A</a>
</div>
<div class="col col-20 col-offset-20 col-center">
<a class="button button-icon icon ion-heart"></a>
</div>
<div class="col col-20 col-center">
<a class="button button-icon icon ion-android-share-alt" ng-click="sharePost(post.url)"></a>
</div>
</div>
</ion-footer-bar>
</ion-view>

View file

@ -0,0 +1,4 @@
<ion-nav-view class="auth-outer">
<div multi-bg="['img/bg-gif.gif']"></div>
<!-- <div multi-bg="['img/bg-img.jpg']"></div> -->
</ion-nav-view>

View file

@ -0,0 +1,30 @@
<ion-view class="forgot-password-view auth-view" cache-view="false">
<ion-content scroll="false">
<div class="row">
<div class="col col-center">
<div class="card forgot-password-container">
<form name="forgot_password_form" class="" novalidate>
<div class="item item-body">
<label class="item item-input">
<input type="email" placeholder="Email" name="user_email" ng-model="user.email" required>
</label>
</div>
<div class="item item-body bottom-content">
<button type="submit" class="button button-positive button-block" ng-click="recoverPassword()" ng-disabled="forgot_password_form.$invalid">
Recover it
</button>
</div>
</form>
</div>
<div class="alternative-actions">
<a class="log-in button button-small button-clear button-light" ui-sref="auth.login">
Log In
</a>
<a class="sign-up button button-small button-clear button-light" ui-sref="auth.signup">
Sign Up
</a>
</div>
</div>
</div>
</ion-content>
</ion-view>

View file

@ -0,0 +1,47 @@
<ion-view class="login-view auth-view" cache-view="false">
<ion-content scroll="false">
<div class="row">
<div class="col col-center">
<div class="card login-container" content-tabs tabsdata='tabsdata'>
<form name="login_form" class="" novalidate ng-cloak>
<my-tabs>
<my-tab title="Email">
<div class="list">
<label class="item item-input">
<input type="email" placeholder="Email" name="user_email" ng-model="user.email" required>
</label>
<label class="item item-input" show-hide-container>
<input type="password" placeholder="Password" name="user_password" ng-model="user.password" required show-hide-input>
</label>
</div>
</my-tab>
<my-tab title="Phone">
<div class="list">
<label class="item item-input">
<input type="text" placeholder="Phone number" name="user_phone" ng-model="user.phone" required>
</label>
<label class="item item-input" show-hide-container>
<input type="password" placeholder="PIN" name="user_pin" ng-model="user.pin" required valid-pin="user.pin" show-hide-input>
</label>
</div>
</my-tab>
</my-tabs>
<div class="item item-body bottom-content">
<button type="submit" class="button button-positive button-block" ng-click="doLogIn()" ng-disabled="(selected_tab=='Email') ? (login_form.user_email.$invalid || login_form.user_password.$invalid) : ((selected_tab=='Phone') ? (login_form.user_phone.$invalid || login_form.user_pin.$invalid) : false)">
Log In
</button>
</div>
</form>
</div>
<div class="alternative-actions">
<a class="forgot-password button button-small button-clear button-light" ui-sref="auth.forgot-password">
Forgot Password?
</a>
<a class="sign-up button button-small button-clear button-light" ui-sref="auth.signup">
Sign Up
</a>
</div>
</div>
</div>
</ion-content>
</ion-view>

View file

@ -0,0 +1,30 @@
<ion-view class="signup-view auth-view" cache-view="false">
<ion-content scroll="false">
<div class="row">
<div class="col col-center">
<div class="card sign-up-container">
<form name="signup_form" class="" novalidate>
<div class="item item-body">
<label class="item item-input">
<input type="email" placeholder="Email" name="user_email" ng-model="user.email" required>
</label>
<label class="item item-input" show-hide-container>
<input type="password" placeholder="Password" name="user_password" ng-model="user.password" required show-hide-input>
</label>
</div>
<div class="item item-body bottom-content">
<button type="submit" class="button button-assertive button-block" ng-click="doSignUp()" ng-disabled="signup_form.$invalid">
Sign Up
</button>
</div>
</form>
</div>
<div class="alternative-actions">
<a class="log-in button button-small button-clear button-light" ui-sref="auth.login">
Log In
</a>
</div>
</div>
</div>
</ion-content>
</ion-view>

View file

@ -0,0 +1,19 @@
<ion-view class="walkthrough-view" cache-view="false">
<ion-content scroll="false">
<div class="top-content row">
<div class="col col-center">
<img ng-src="img/logo.png">
</div>
</div>
<div class="bottom-content row">
<div class="col col-center">
<a class="login button button-block button-stable" ui-sref="auth.login">
Log In
</a>
<a class="sign-up button button-block button-stable" ui-sref="auth.signup">
Sign Up
</a>
</div>
</div>
</ion-content>
</ion-view>

View file

@ -0,0 +1 @@
<youtube-video video-id="videoId" player="yt_video" player-vars="playerVars"></youtube-video>

View file

@ -0,0 +1,7 @@
<div class="multi-bg-outer" ng-class="{ 'finish-loading': loaded }">
<img bg class="multi-bg {{ helperClass }}" ng-src="{{ bg_img }}"/>
<span class="bg-overlay"></span>
<ion-spinner ng-show="!loaded" class="spinner-on-load"></ion-spinner>
<!-- <span ng-show="!loaded" class="spinner-on-load ion-load-c"></span> -->
<ng-transclude></ng-transclude>
</div>

View file

@ -0,0 +1 @@
<div class="tab-content ng-cloak ng-hide" ng-cloak ng-show="selected" ng-transclude></div>

View file

@ -0,0 +1,10 @@
<div class="item item-divider card-heding">
<div class="tabs-striped">
<div class="tabs">
<a ng-repeat="tab in tabs" ng-click="select(tab)" ng-class="{ active: tab.selected }" class="tab-item">{{tab.title}}</a>
</div>
</div>
</div>
<div class="item item-body">
<div class="tabs-content" ng-transclude></div>
</div>

View file

@ -0,0 +1,5 @@
<div class="pre-img {{ratio}} {{ helperClass }}" ng-class="{ 'finish-loading': loaded }">
<ion-spinner ng-show="!loaded" class="spinner-on-load"></ion-spinner>
<!-- <span ng-show="!loaded" class="spinner-on-load ion-load-c"></span> -->
<ng-transclude></ng-transclude>
</div>

View file

@ -0,0 +1,6 @@
<div class="show-hide-input" ng-transclude>
</div>
<a class="toggle-view-anchor" on-touch="toggleType($event)">
<span class="ion-eye-disabled" ng-show="show"></span>
<span class="ion-eye" ng-show="!show"></span>
</a>