First Commit
191
hackatonApp/www/feeds-categories.json
Normal 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/"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
BIN
hackatonApp/www/img/bg-gif.gif
Normal file
|
After Width: | Height: | Size: 564 KiB |
BIN
hackatonApp/www/img/bg-img.jpg
Normal file
|
After Width: | Height: | Size: 103 KiB |
BIN
hackatonApp/www/img/feeds/assets/business-1.jpg
Normal file
|
After Width: | Height: | Size: 35 KiB |
BIN
hackatonApp/www/img/feeds/assets/business-2.jpg
Normal file
|
After Width: | Height: | Size: 21 KiB |
BIN
hackatonApp/www/img/feeds/assets/business-3.jpg
Normal file
|
After Width: | Height: | Size: 26 KiB |
BIN
hackatonApp/www/img/feeds/assets/entertainment-1.jpg
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
hackatonApp/www/img/feeds/assets/entertainment-2.jpg
Normal file
|
After Width: | Height: | Size: 9.9 KiB |
BIN
hackatonApp/www/img/feeds/assets/entertainment-3.jpg
Normal file
|
After Width: | Height: | Size: 28 KiB |
BIN
hackatonApp/www/img/feeds/assets/entertainment-4.jpg
Normal file
|
After Width: | Height: | Size: 34 KiB |
BIN
hackatonApp/www/img/feeds/assets/news-1.jpg
Normal file
|
After Width: | Height: | Size: 60 KiB |
BIN
hackatonApp/www/img/feeds/assets/news-2.jpg
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
hackatonApp/www/img/feeds/assets/politics-1.jpg
Normal file
|
After Width: | Height: | Size: 7.7 KiB |
BIN
hackatonApp/www/img/feeds/assets/politics-2.jpg
Normal file
|
After Width: | Height: | Size: 20 KiB |
BIN
hackatonApp/www/img/feeds/assets/sports-1.jpg
Normal file
|
After Width: | Height: | Size: 8.1 KiB |
BIN
hackatonApp/www/img/feeds/assets/sports-2.jpg
Normal file
|
After Width: | Height: | Size: 17 KiB |
BIN
hackatonApp/www/img/feeds/assets/sports-3.jpg
Normal file
|
After Width: | Height: | Size: 7.2 KiB |
BIN
hackatonApp/www/img/feeds/assets/sports-4.jpg
Normal file
|
After Width: | Height: | Size: 8.9 KiB |
BIN
hackatonApp/www/img/feeds/assets/technology-1.jpg
Normal file
|
After Width: | Height: | Size: 26 KiB |
BIN
hackatonApp/www/img/feeds/assets/technology-2.jpg
Normal file
|
After Width: | Height: | Size: 65 KiB |
BIN
hackatonApp/www/img/feeds/business.jpg
Normal file
|
After Width: | Height: | Size: 26 KiB |
BIN
hackatonApp/www/img/feeds/entertainment.jpg
Normal file
|
After Width: | Height: | Size: 34 KiB |
BIN
hackatonApp/www/img/feeds/logos/bbc.jpg
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
hackatonApp/www/img/feeds/logos/cnet.jpg
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
BIN
hackatonApp/www/img/feeds/logos/cnn.jpg
Normal file
|
After Width: | Height: | Size: 2.4 KiB |
BIN
hackatonApp/www/img/feeds/logos/espn.jpg
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
hackatonApp/www/img/feeds/logos/forbes.jpg
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
hackatonApp/www/img/feeds/logos/fox-sports.jpg
Normal file
|
After Width: | Height: | Size: 7.2 KiB |
BIN
hackatonApp/www/img/feeds/logos/inc.jpg
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
hackatonApp/www/img/feeds/logos/reuters.jpg
Normal file
|
After Width: | Height: | Size: 3.3 KiB |
BIN
hackatonApp/www/img/feeds/logos/techcrunch.jpg
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
hackatonApp/www/img/feeds/logos/techradar.jpg
Normal file
|
After Width: | Height: | Size: 2.2 KiB |
BIN
hackatonApp/www/img/feeds/logos/the-economist.jpg
Normal file
|
After Width: | Height: | Size: 2 KiB |
BIN
hackatonApp/www/img/feeds/logos/the-guardian.jpg
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
hackatonApp/www/img/feeds/logos/the-hollywood-reporter.jpg
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
hackatonApp/www/img/feeds/logos/the-nation.jpg
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
hackatonApp/www/img/feeds/logos/tmz.jpg
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
hackatonApp/www/img/feeds/logos/washington-post.jpg
Normal file
|
After Width: | Height: | Size: 2.2 KiB |
BIN
hackatonApp/www/img/feeds/news.jpg
Normal file
|
After Width: | Height: | Size: 60 KiB |
BIN
hackatonApp/www/img/feeds/politics.jpg
Normal file
|
After Width: | Height: | Size: 20 KiB |
BIN
hackatonApp/www/img/feeds/sports.jpg
Normal file
|
After Width: | Height: | Size: 8.9 KiB |
BIN
hackatonApp/www/img/feeds/technology.jpg
Normal file
|
After Width: | Height: | Size: 26 KiB |
BIN
hackatonApp/www/img/ionic.png
Normal file
|
After Width: | Height: | Size: 2.6 KiB |
BIN
hackatonApp/www/img/logo.png
Normal file
|
After Width: | Height: | Size: 26 KiB |
40
hackatonApp/www/index.html
Normal 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 'self' 'unsafe-inline' 'unsafe-eval' *; style-src 'self' 'unsafe-inline' *">
|
||||
<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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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);
|
||||
};
|
||||
|
||||
})
|
||||
|
||||
|
||||
;
|
||||
35
hackatonApp/www/views/app/bookmarks.html
Normal 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>
|
||||
21
hackatonApp/www/views/app/feeds/category-feeds.html
Normal 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>
|
||||
34
hackatonApp/www/views/app/feeds/feed-entries.html
Normal 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>
|
||||
21
hackatonApp/www/views/app/feeds/feeds-categories.html
Normal 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>
|
||||
69
hackatonApp/www/views/app/forms.html
Normal 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>
|
||||
28
hackatonApp/www/views/app/layouts/layouts.html
Normal 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>
|
||||
19
hackatonApp/www/views/app/layouts/slider.html
Normal 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>
|
||||
34
hackatonApp/www/views/app/layouts/tinder-cards.html
Normal 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>
|
||||
28
hackatonApp/www/views/app/miscellaneous/image-picker.html
Normal 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>
|
||||
38
hackatonApp/www/views/app/miscellaneous/maps.html
Normal 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>
|
||||
66
hackatonApp/www/views/app/miscellaneous/miscellaneous.html
Normal 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>
|
||||
26
hackatonApp/www/views/app/profile.html
Normal 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>
|
||||
50
hackatonApp/www/views/app/settings.html
Normal 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>
|
||||
58
hackatonApp/www/views/app/side-menu.html
Normal 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>
|
||||
41
hackatonApp/www/views/app/wordpress/wordpress.html
Normal 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>
|
||||
32
hackatonApp/www/views/app/wordpress/wordpress_post.html
Normal 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>
|
||||
4
hackatonApp/www/views/auth/auth.html
Normal 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>
|
||||
30
hackatonApp/www/views/auth/forgot-password.html
Normal 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>
|
||||
47
hackatonApp/www/views/auth/login.html
Normal 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>
|
||||
30
hackatonApp/www/views/auth/signup.html
Normal 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>
|
||||
19
hackatonApp/www/views/auth/walkthrough.html
Normal 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>
|
||||
1
hackatonApp/www/views/common/ionic-youtube-video.html
Normal file
|
|
@ -0,0 +1 @@
|
|||
<youtube-video video-id="videoId" player="yt_video" player-vars="playerVars"></youtube-video>
|
||||
7
hackatonApp/www/views/common/multi-bg.html
Normal 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>
|
||||
1
hackatonApp/www/views/common/my-tab.html
Normal file
|
|
@ -0,0 +1 @@
|
|||
<div class="tab-content ng-cloak ng-hide" ng-cloak ng-show="selected" ng-transclude></div>
|
||||
10
hackatonApp/www/views/common/my-tabs.html
Normal 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>
|
||||
5
hackatonApp/www/views/common/pre-img.html
Normal 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>
|
||||
6
hackatonApp/www/views/common/show-hide-password.html
Normal 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>
|
||||