Add turbolinks, remove useless angularjs code
This commit is contained in:
parent
02f09f1d38
commit
27314da99a
4
Gemfile
4
Gemfile
|
@ -11,9 +11,9 @@ gem 'jquery-rails'
|
|||
gem 'foundation-rails', '~> 6.2.1'
|
||||
gem 'foundation-icons-sass-rails'
|
||||
gem 'font-awesome-sass'
|
||||
gem 'angularjs-rails'
|
||||
gem 'carrierwave'
|
||||
gem 'kaminari', git: 'git@github.com:amatsuda/kaminari.git'
|
||||
gem 'turbolinks', '~> 5.x'
|
||||
|
||||
gem 'jbuilder'
|
||||
gem 'pg'
|
||||
|
@ -33,7 +33,7 @@ gem 'redis-namespace'
|
|||
gem 'rest-client'
|
||||
gem 'newrelic_rpm'
|
||||
|
||||
gem 'unicorn'
|
||||
gem 'puma'
|
||||
|
||||
gem 'mina', require: false
|
||||
gem 'mina-multistage', require: false
|
||||
|
|
12
Gemfile.lock
12
Gemfile.lock
|
@ -136,7 +136,6 @@ GEM
|
|||
railties (>= 4.2.0)
|
||||
thor (>= 0.14, < 2.0)
|
||||
json (1.8.3)
|
||||
kgio (2.10.0)
|
||||
listen (3.0.6)
|
||||
rb-fsevent (>= 0.9.3)
|
||||
rb-inotify (>= 0.9.7)
|
||||
|
@ -178,6 +177,7 @@ GEM
|
|||
pry (>= 0.9.10, < 0.11.0)
|
||||
pry-rails (0.3.4)
|
||||
pry (>= 0.9.10)
|
||||
puma (3.4.0)
|
||||
quiet_assets (1.1.0)
|
||||
railties (>= 3.1, < 5.0)
|
||||
rack (2.0.0.alpha)
|
||||
|
@ -211,7 +211,6 @@ GEM
|
|||
method_source
|
||||
rake (>= 0.8.7)
|
||||
thor (>= 0.18.1, < 2.0)
|
||||
raindrops (0.16.0)
|
||||
rake (11.1.2)
|
||||
rb-fsevent (0.9.7)
|
||||
rb-inotify (0.9.7)
|
||||
|
@ -299,6 +298,9 @@ GEM
|
|||
thor (0.19.1)
|
||||
thread_safe (0.3.5)
|
||||
tilt (2.0.2)
|
||||
turbolinks (5.0.0.beta2)
|
||||
turbolinks-source
|
||||
turbolinks-source (5.0.0.beta4)
|
||||
tzinfo (1.2.2)
|
||||
thread_safe (~> 0.1)
|
||||
uglifier (3.0.0)
|
||||
|
@ -306,9 +308,6 @@ GEM
|
|||
unf (0.1.4)
|
||||
unf_ext
|
||||
unf_ext (0.0.7.2)
|
||||
unicorn (5.1.0)
|
||||
kgio (~> 2.6)
|
||||
raindrops (~> 0.7)
|
||||
websocket-driver (0.6.3)
|
||||
websocket-extensions (>= 0.1.0)
|
||||
websocket-extensions (0.1.2)
|
||||
|
@ -350,6 +349,7 @@ DEPENDENCIES
|
|||
pg
|
||||
pry-nav
|
||||
pry-rails
|
||||
puma
|
||||
quiet_assets
|
||||
rack-cors
|
||||
rails (>= 5.0.0.beta3, < 5.1)
|
||||
|
@ -366,8 +366,8 @@ DEPENDENCIES
|
|||
slim-rails
|
||||
spring
|
||||
spring-watcher-listen (~> 2.0.0)
|
||||
turbolinks (~> 5.x)
|
||||
uglifier (>= 2.7.2)
|
||||
unicorn
|
||||
|
||||
BUNDLED WITH
|
||||
1.11.2
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/
|
||||
#
|
||||
|
||||
$(document).ready ->
|
||||
$(document).on 'turbolinks:load', ->
|
||||
$('a#upload_photo').click ->
|
||||
$('input[type=file]').show().focus().click().hide()
|
||||
false
|
||||
|
|
|
@ -1,589 +0,0 @@
|
|||
/**
|
||||
* x is a value between 0 and 1, indicating where in the animation you are.
|
||||
*/
|
||||
var duScrollDefaultEasing = function (x) {
|
||||
'use strict';
|
||||
|
||||
if(x < 0.5) {
|
||||
return Math.pow(x*2, 2)/2;
|
||||
}
|
||||
return 1-Math.pow((1-x)*2, 2)/2;
|
||||
};
|
||||
|
||||
angular.module('duScroll', [
|
||||
'duScroll.scrollspy',
|
||||
'duScroll.smoothScroll',
|
||||
'duScroll.scrollContainer',
|
||||
'duScroll.spyContext',
|
||||
'duScroll.scrollHelpers'
|
||||
])
|
||||
//Default animation duration for smoothScroll directive
|
||||
.value('duScrollDuration', 350)
|
||||
//Scrollspy debounce interval, set to 0 to disable
|
||||
.value('duScrollSpyWait', 100)
|
||||
//Wether or not multiple scrollspies can be active at once
|
||||
.value('duScrollGreedy', false)
|
||||
//Default offset for smoothScroll directive
|
||||
.value('duScrollOffset', 0)
|
||||
//Default easing function for scroll animation
|
||||
.value('duScrollEasing', duScrollDefaultEasing);
|
||||
|
||||
|
||||
angular.module('duScroll.scrollHelpers', ['duScroll.requestAnimation'])
|
||||
.run(["$window", "$q", "cancelAnimation", "requestAnimation", "duScrollEasing", "duScrollDuration", "duScrollOffset", function($window, $q, cancelAnimation, requestAnimation, duScrollEasing, duScrollDuration, duScrollOffset) {
|
||||
'use strict';
|
||||
|
||||
var proto = angular.element.prototype;
|
||||
|
||||
var isDocument = function(el) {
|
||||
return (typeof HTMLDocument !== 'undefined' && el instanceof HTMLDocument) || (el.nodeType && el.nodeType === el.DOCUMENT_NODE);
|
||||
};
|
||||
|
||||
var isElement = function(el) {
|
||||
return (typeof HTMLElement !== 'undefined' && el instanceof HTMLElement) || (el.nodeType && el.nodeType === el.ELEMENT_NODE);
|
||||
};
|
||||
|
||||
var unwrap = function(el) {
|
||||
return isElement(el) || isDocument(el) ? el : el[0];
|
||||
};
|
||||
|
||||
proto.scrollTo = function(left, top, duration, easing) {
|
||||
var aliasFn;
|
||||
if(angular.isElement(left)) {
|
||||
aliasFn = this.scrollToElement;
|
||||
} else if(duration) {
|
||||
aliasFn = this.scrollToAnimated;
|
||||
}
|
||||
if(aliasFn) {
|
||||
return aliasFn.apply(this, arguments);
|
||||
}
|
||||
var el = unwrap(this);
|
||||
if(isDocument(el)) {
|
||||
return $window.scrollTo(left, top);
|
||||
}
|
||||
el.scrollLeft = left;
|
||||
el.scrollTop = top;
|
||||
};
|
||||
|
||||
var scrollAnimation, deferred;
|
||||
proto.scrollToAnimated = function(left, top, duration, easing) {
|
||||
if(duration && !easing) {
|
||||
easing = duScrollEasing;
|
||||
}
|
||||
var startLeft = this.scrollLeft(),
|
||||
startTop = this.scrollTop(),
|
||||
deltaLeft = Math.round(left - startLeft),
|
||||
deltaTop = Math.round(top - startTop);
|
||||
|
||||
var startTime = null;
|
||||
var el = this;
|
||||
|
||||
var cancelOnEvents = 'scroll mousedown mousewheel touchmove keydown';
|
||||
var cancelScrollAnimation = function($event) {
|
||||
if (!$event || $event.which > 0) {
|
||||
el.unbind(cancelOnEvents, cancelScrollAnimation);
|
||||
cancelAnimation(scrollAnimation);
|
||||
deferred.reject();
|
||||
scrollAnimation = null;
|
||||
}
|
||||
};
|
||||
|
||||
if(scrollAnimation) {
|
||||
cancelScrollAnimation();
|
||||
}
|
||||
deferred = $q.defer();
|
||||
|
||||
if(!deltaLeft && !deltaTop) {
|
||||
deferred.resolve();
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
var animationStep = function(timestamp) {
|
||||
if (startTime === null) {
|
||||
startTime = timestamp;
|
||||
}
|
||||
|
||||
var progress = timestamp - startTime;
|
||||
var percent = (progress >= duration ? 1 : easing(progress/duration));
|
||||
|
||||
el.scrollTo(
|
||||
startLeft + Math.ceil(deltaLeft * percent),
|
||||
startTop + Math.ceil(deltaTop * percent)
|
||||
);
|
||||
if(percent < 1) {
|
||||
scrollAnimation = requestAnimation(animationStep);
|
||||
} else {
|
||||
el.unbind(cancelOnEvents, cancelScrollAnimation);
|
||||
scrollAnimation = null;
|
||||
deferred.resolve();
|
||||
}
|
||||
};
|
||||
|
||||
//Fix random mobile safari bug when scrolling to top by hitting status bar
|
||||
el.scrollTo(startLeft, startTop);
|
||||
|
||||
el.bind(cancelOnEvents, cancelScrollAnimation);
|
||||
|
||||
scrollAnimation = requestAnimation(animationStep);
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
proto.scrollToElement = function(target, offset, duration, easing) {
|
||||
var el = unwrap(this);
|
||||
if(!angular.isNumber(offset) || isNaN(offset)) {
|
||||
offset = duScrollOffset;
|
||||
}
|
||||
var top = this.scrollTop() + unwrap(target).getBoundingClientRect().top - offset;
|
||||
if(isElement(el)) {
|
||||
top -= el.getBoundingClientRect().top;
|
||||
}
|
||||
return this.scrollTo(0, top, duration, easing);
|
||||
};
|
||||
|
||||
var overloaders = {
|
||||
scrollLeft: function(value, duration, easing) {
|
||||
if(angular.isNumber(value)) {
|
||||
return this.scrollTo(value, this.scrollTop(), duration, easing);
|
||||
}
|
||||
var el = unwrap(this);
|
||||
if(isDocument(el)) {
|
||||
return $window.scrollX || document.documentElement.scrollLeft || document.body.scrollLeft;
|
||||
}
|
||||
return el.scrollLeft;
|
||||
},
|
||||
scrollTop: function(value, duration, easing) {
|
||||
if(angular.isNumber(value)) {
|
||||
return this.scrollTo(this.scrollTop(), value, duration, easing);
|
||||
}
|
||||
var el = unwrap(this);
|
||||
if(isDocument(el)) {
|
||||
return $window.scrollY || document.documentElement.scrollTop || document.body.scrollTop;
|
||||
}
|
||||
return el.scrollTop;
|
||||
}
|
||||
};
|
||||
|
||||
proto.scrollToElementAnimated = function(target, offset, duration, easing) {
|
||||
return this.scrollToElement(target, offset, duration || duScrollDuration, easing);
|
||||
};
|
||||
|
||||
proto.scrollTopAnimated = function(top, duration, easing) {
|
||||
return this.scrollTop(top, duration || duScrollDuration, easing);
|
||||
};
|
||||
|
||||
proto.scrollLeftAnimated = function(left, duration, easing) {
|
||||
return this.scrollLeft(left, duration || duScrollDuration, easing);
|
||||
};
|
||||
|
||||
//Add duration and easing functionality to existing jQuery getter/setters
|
||||
var overloadScrollPos = function(superFn, overloadFn) {
|
||||
return function(value, duration, easing) {
|
||||
if(duration) {
|
||||
return overloadFn.apply(this, arguments);
|
||||
}
|
||||
return superFn.apply(this, arguments);
|
||||
};
|
||||
};
|
||||
|
||||
for(var methodName in overloaders) {
|
||||
proto[methodName] = (proto[methodName] ? overloadScrollPos(proto[methodName], overloaders[methodName]) : overloaders[methodName]);
|
||||
}
|
||||
}]);
|
||||
|
||||
|
||||
//Adapted from https://gist.github.com/paulirish/1579671
|
||||
angular.module('duScroll.polyfill', [])
|
||||
.factory('polyfill', ["$window", function($window) {
|
||||
'use strict';
|
||||
|
||||
var vendors = ['webkit', 'moz', 'o', 'ms'];
|
||||
|
||||
return function(fnName, fallback) {
|
||||
if($window[fnName]) {
|
||||
return $window[fnName];
|
||||
}
|
||||
var suffix = fnName.substr(0, 1).toUpperCase() + fnName.substr(1);
|
||||
for(var key, i = 0; i < vendors.length; i++) {
|
||||
key = vendors[i]+suffix;
|
||||
if($window[key]) {
|
||||
return $window[key];
|
||||
}
|
||||
}
|
||||
return fallback;
|
||||
};
|
||||
}]);
|
||||
|
||||
angular.module('duScroll.requestAnimation', ['duScroll.polyfill'])
|
||||
.factory('requestAnimation', ["polyfill", "$timeout", function(polyfill, $timeout) {
|
||||
'use strict';
|
||||
|
||||
var lastTime = 0;
|
||||
var fallback = function(callback, element) {
|
||||
var currTime = new Date().getTime();
|
||||
var timeToCall = Math.max(0, 16 - (currTime - lastTime));
|
||||
var id = $timeout(function() { callback(currTime + timeToCall); },
|
||||
timeToCall);
|
||||
lastTime = currTime + timeToCall;
|
||||
return id;
|
||||
};
|
||||
|
||||
return polyfill('requestAnimationFrame', fallback);
|
||||
}])
|
||||
.factory('cancelAnimation', ["polyfill", "$timeout", function(polyfill, $timeout) {
|
||||
'use strict';
|
||||
|
||||
var fallback = function(promise) {
|
||||
$timeout.cancel(promise);
|
||||
};
|
||||
|
||||
return polyfill('cancelAnimationFrame', fallback);
|
||||
}]);
|
||||
|
||||
|
||||
angular.module('duScroll.spyAPI', ['duScroll.scrollContainerAPI'])
|
||||
.factory('spyAPI', ["$rootScope", "$timeout", "scrollContainerAPI", "duScrollGreedy", "duScrollSpyWait", function($rootScope, $timeout, scrollContainerAPI, duScrollGreedy, duScrollSpyWait) {
|
||||
'use strict';
|
||||
|
||||
var createScrollHandler = function(context) {
|
||||
var timer = false, queued = false;
|
||||
var handler = function() {
|
||||
queued = false;
|
||||
var container = context.container,
|
||||
containerEl = container[0],
|
||||
containerOffset = 0;
|
||||
|
||||
if (typeof HTMLElement !== 'undefined' && containerEl instanceof HTMLElement || containerEl.nodeType && containerEl.nodeType === containerEl.ELEMENT_NODE) {
|
||||
containerOffset = containerEl.getBoundingClientRect().top;
|
||||
}
|
||||
|
||||
var i, currentlyActive, toBeActive, spies, spy, pos;
|
||||
spies = context.spies;
|
||||
currentlyActive = context.currentlyActive;
|
||||
toBeActive = undefined;
|
||||
|
||||
for(i = 0; i < spies.length; i++) {
|
||||
spy = spies[i];
|
||||
pos = spy.getTargetPosition();
|
||||
if (!pos) continue;
|
||||
|
||||
if(pos.top + spy.offset - containerOffset < 20 && (pos.top*-1 + containerOffset) < pos.height) {
|
||||
if(!toBeActive || toBeActive.top < pos.top) {
|
||||
toBeActive = {
|
||||
top: pos.top,
|
||||
spy: spy
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
if(toBeActive) {
|
||||
toBeActive = toBeActive.spy;
|
||||
}
|
||||
if(currentlyActive === toBeActive || (duScrollGreedy && !toBeActive)) return;
|
||||
if(currentlyActive) {
|
||||
currentlyActive.$element.removeClass('active');
|
||||
$rootScope.$broadcast('duScrollspy:becameInactive', currentlyActive.$element);
|
||||
}
|
||||
if(toBeActive) {
|
||||
toBeActive.$element.addClass('active');
|
||||
$rootScope.$broadcast('duScrollspy:becameActive', toBeActive.$element);
|
||||
}
|
||||
context.currentlyActive = toBeActive;
|
||||
};
|
||||
|
||||
if(!duScrollSpyWait) {
|
||||
return handler;
|
||||
}
|
||||
|
||||
//Debounce for potential performance savings
|
||||
return function() {
|
||||
if(!timer) {
|
||||
handler();
|
||||
timer = $timeout(function() {
|
||||
timer = false;
|
||||
if(queued) {
|
||||
handler();
|
||||
}
|
||||
}, duScrollSpyWait, false);
|
||||
} else {
|
||||
queued = true;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
var contexts = {};
|
||||
|
||||
var createContext = function($scope) {
|
||||
var id = $scope.$id;
|
||||
var context = {
|
||||
spies: []
|
||||
};
|
||||
|
||||
context.handler = createScrollHandler(context);
|
||||
contexts[id] = context;
|
||||
|
||||
$scope.$on('$destroy', function() {
|
||||
destroyContext($scope);
|
||||
});
|
||||
|
||||
return id;
|
||||
};
|
||||
|
||||
var destroyContext = function($scope) {
|
||||
var id = $scope.$id;
|
||||
var context = contexts[id], container = context.container;
|
||||
if(container) {
|
||||
container.off('scroll', context.handler);
|
||||
}
|
||||
delete contexts[id];
|
||||
};
|
||||
|
||||
var defaultContextId = createContext($rootScope);
|
||||
|
||||
var getContextForScope = function(scope) {
|
||||
if(contexts[scope.$id]) {
|
||||
return contexts[scope.$id];
|
||||
}
|
||||
if(scope.$parent) {
|
||||
return getContextForScope(scope.$parent);
|
||||
}
|
||||
return contexts[defaultContextId];
|
||||
};
|
||||
|
||||
var getContextForSpy = function(spy) {
|
||||
var context, contextId, scope = spy.$element.scope();
|
||||
if(scope) {
|
||||
return getContextForScope(scope);
|
||||
}
|
||||
//No scope, most likely destroyed
|
||||
for(contextId in contexts) {
|
||||
context = contexts[contextId];
|
||||
if(context.spies.indexOf(spy) !== -1) {
|
||||
return context;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var isElementInDocument = function(element) {
|
||||
while (element.parentNode) {
|
||||
element = element.parentNode;
|
||||
if (element === document) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
var addSpy = function(spy) {
|
||||
var context = getContextForSpy(spy);
|
||||
if (!context) return;
|
||||
context.spies.push(spy);
|
||||
if (!context.container || !isElementInDocument(context.container)) {
|
||||
if(context.container) {
|
||||
context.container.off('scroll', context.handler);
|
||||
}
|
||||
context.container = scrollContainerAPI.getContainer(spy.$element.scope());
|
||||
context.container.on('scroll', context.handler).triggerHandler('scroll');
|
||||
}
|
||||
};
|
||||
|
||||
var removeSpy = function(spy) {
|
||||
var context = getContextForSpy(spy);
|
||||
if(spy === context.currentlyActive) {
|
||||
context.currentlyActive = null;
|
||||
}
|
||||
var i = context.spies.indexOf(spy);
|
||||
if(i !== -1) {
|
||||
context.spies.splice(i, 1);
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
addSpy: addSpy,
|
||||
removeSpy: removeSpy,
|
||||
createContext: createContext,
|
||||
destroyContext: destroyContext,
|
||||
getContextForScope: getContextForScope
|
||||
};
|
||||
}]);
|
||||
|
||||
|
||||
angular.module('duScroll.scrollContainerAPI', [])
|
||||
.factory('scrollContainerAPI', ["$document", function($document) {
|
||||
'use strict';
|
||||
|
||||
var containers = {};
|
||||
|
||||
var setContainer = function(scope, element) {
|
||||
var id = scope.$id;
|
||||
containers[id] = element;
|
||||
return id;
|
||||
};
|
||||
|
||||
var getContainerId = function(scope) {
|
||||
if(containers[scope.$id]) {
|
||||
return scope.$id;
|
||||
}
|
||||
if(scope.$parent) {
|
||||
return getContainerId(scope.$parent);
|
||||
}
|
||||
return;
|
||||
};
|
||||
|
||||
var getContainer = function(scope) {
|
||||
var id = getContainerId(scope);
|
||||
return id ? containers[id] : $document;
|
||||
};
|
||||
|
||||
var removeContainer = function(scope) {
|
||||
var id = getContainerId(scope);
|
||||
if(id) {
|
||||
delete containers[id];
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
getContainerId: getContainerId,
|
||||
getContainer: getContainer,
|
||||
setContainer: setContainer,
|
||||
removeContainer: removeContainer
|
||||
};
|
||||
}]);
|
||||
|
||||
|
||||
angular.module('duScroll.smoothScroll', ['duScroll.scrollHelpers', 'duScroll.scrollContainerAPI'])
|
||||
.directive('duSmoothScroll', ["duScrollDuration", "duScrollOffset", "scrollContainerAPI", function(duScrollDuration, duScrollOffset, scrollContainerAPI) {
|
||||
'use strict';
|
||||
|
||||
return {
|
||||
link : function($scope, $element, $attr) {
|
||||
$element.on('click', function(e) {
|
||||
if(!$attr.href || $attr.href.indexOf('#') === -1) return;
|
||||
|
||||
var target = document.getElementById($attr.href.replace(/.*(?=#[^\s]+$)/, '').substring(1));
|
||||
if(!target || !target.getBoundingClientRect) return;
|
||||
|
||||
if (e.stopPropagation) e.stopPropagation();
|
||||
if (e.preventDefault) e.preventDefault();
|
||||
|
||||
var offset = $attr.offset ? parseInt($attr.offset, 10) : duScrollOffset;
|
||||
var duration = $attr.duration ? parseInt($attr.duration, 10) : duScrollDuration;
|
||||
var container = scrollContainerAPI.getContainer($scope);
|
||||
|
||||
container.scrollToElement(
|
||||
angular.element(target),
|
||||
isNaN(offset) ? 0 : offset,
|
||||
isNaN(duration) ? 0 : duration
|
||||
);
|
||||
});
|
||||
}
|
||||
};
|
||||
}]);
|
||||
|
||||
|
||||
angular.module('duScroll.spyContext', ['duScroll.spyAPI'])
|
||||
.directive('duSpyContext', ["spyAPI", function(spyAPI) {
|
||||
'use strict';
|
||||
|
||||
return {
|
||||
restrict: 'A',
|
||||
scope: true,
|
||||
compile: function compile(tElement, tAttrs, transclude) {
|
||||
return {
|
||||
pre: function preLink($scope, iElement, iAttrs, controller) {
|
||||
spyAPI.createContext($scope);
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
}]);
|
||||
|
||||
|
||||
angular.module('duScroll.scrollContainer', ['duScroll.scrollContainerAPI'])
|
||||
.directive('duScrollContainer', ["scrollContainerAPI", function(scrollContainerAPI){
|
||||
'use strict';
|
||||
|
||||
return {
|
||||
restrict: 'A',
|
||||
scope: true,
|
||||
compile: function compile(tElement, tAttrs, transclude) {
|
||||
return {
|
||||
pre: function preLink($scope, iElement, iAttrs, controller) {
|
||||
iAttrs.$observe('duScrollContainer', function(element) {
|
||||
if(angular.isString(element)) {
|
||||
element = document.getElementById(element);
|
||||
}
|
||||
|
||||
element = (angular.isElement(element) ? angular.element(element) : iElement);
|
||||
scrollContainerAPI.setContainer($scope, element);
|
||||
$scope.$on('$destroy', function() {
|
||||
scrollContainerAPI.removeContainer($scope);
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
}]);
|
||||
|
||||
|
||||
angular.module('duScroll.scrollspy', ['duScroll.spyAPI'])
|
||||
.directive('duScrollspy', ["spyAPI", "duScrollOffset", "$timeout", "$rootScope", function(spyAPI, duScrollOffset, $timeout, $rootScope) {
|
||||
'use strict';
|
||||
|
||||
var Spy = function(targetElementOrId, $element, offset) {
|
||||
if(angular.isElement(targetElementOrId)) {
|
||||
this.target = targetElementOrId;
|
||||
} else if(angular.isString(targetElementOrId)) {
|
||||
this.targetId = targetElementOrId;
|
||||
}
|
||||
this.$element = $element;
|
||||
this.offset = offset;
|
||||
};
|
||||
|
||||
Spy.prototype.getTargetElement = function() {
|
||||
if (!this.target && this.targetId) {
|
||||
this.target = document.getElementById(this.targetId);
|
||||
}
|
||||
return this.target;
|
||||
};
|
||||
|
||||
Spy.prototype.getTargetPosition = function() {
|
||||
var target = this.getTargetElement();
|
||||
if(target) {
|
||||
return target.getBoundingClientRect();
|
||||
}
|
||||
};
|
||||
|
||||
Spy.prototype.flushTargetCache = function() {
|
||||
if(this.targetId) {
|
||||
this.target = undefined;
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
link: function ($scope, $element, $attr) {
|
||||
var href = $attr.ngHref || $attr.href;
|
||||
var targetId;
|
||||
|
||||
if (href && href.indexOf('#') !== -1) {
|
||||
targetId = href.replace(/.*(?=#[^\s]+$)/, '').substring(1);
|
||||
} else if($attr.duScrollspy) {
|
||||
targetId = $attr.duScrollspy;
|
||||
}
|
||||
if(!targetId) return;
|
||||
|
||||
// Run this in the next execution loop so that the scroll context has a chance
|
||||
// to initialize
|
||||
$timeout(function() {
|
||||
var spy = new Spy(targetId, $element, -($attr.offset ? parseInt($attr.offset, 10) : duScrollOffset));
|
||||
spyAPI.addSpy(spy);
|
||||
|
||||
$scope.$on('$destroy', function() {
|
||||
spyAPI.removeSpy(spy);
|
||||
});
|
||||
$scope.$on('$locationChangeSuccess', spy.flushTargetCache.bind(spy));
|
||||
$rootScope.$on('$stateChangeSuccess', spy.flushTargetCache.bind(spy));
|
||||
}, 0, false);
|
||||
}
|
||||
};
|
||||
}]);
|
|
@ -1,15 +0,0 @@
|
|||
#= require angular
|
||||
#= require angular-cookies
|
||||
#= require angular-resource
|
||||
#= require angular-sanitize
|
||||
#= require angular-scroll
|
||||
#= require_self
|
||||
#= require_tree ./angularjs
|
||||
|
||||
@app = angular.module('app', ['ngCookies', 'ngSanitize', 'duScroll'])
|
||||
@app.value('duScrollOffset', 30)
|
||||
|
||||
@app.config(["$httpProvider", (provider) ->
|
||||
provider.defaults.headers.common['X-CSRF-Token'] = $('meta[name=csrf-token]').attr('content')
|
||||
provider.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest'
|
||||
])
|
|
@ -1,36 +0,0 @@
|
|||
@app.controller 'AboutController', [ '$scope', '$timeout', '$http', ($scope, $timeout, $http)->
|
||||
$scope.type = null
|
||||
|
||||
$scope.click = (v)->
|
||||
if $scope.type == v
|
||||
$scope.type = null
|
||||
return
|
||||
$scope.type = v
|
||||
$scope.weixin_click = ->
|
||||
$scope.weixin = !$scope.weixin
|
||||
|
||||
#订阅功能
|
||||
|
||||
$scope.email = ''
|
||||
$scope.subscribe_success = null
|
||||
|
||||
$scope.email_validate = ->
|
||||
$scope.email.match(/@/)
|
||||
|
||||
$scope.subscribe = ()->
|
||||
$http
|
||||
url: '/subscribes'
|
||||
method: 'POST'
|
||||
params:
|
||||
email: $scope.email
|
||||
.success (res)->
|
||||
if res.success
|
||||
$scope.email = ''
|
||||
$scope.subscribe_success = true
|
||||
else
|
||||
$scope.subscribe_success = false
|
||||
$scope.subscribe_fail_msg = res.message
|
||||
$timeout ->
|
||||
$scope.subscribe_success = null
|
||||
, 3000
|
||||
]
|
|
@ -1,14 +0,0 @@
|
|||
@app.controller 'AboutScrollController', [ '$scope', '$document', ($scope, $document)->
|
||||
|
||||
about_id = angular.element(document.getElementById('about'))
|
||||
|
||||
$document.on 'scroll', ()=>
|
||||
$scope.$apply()
|
||||
|
||||
$scope.is_top = ()->
|
||||
$document.scrollTop() <= 0
|
||||
|
||||
|
||||
$scope.to_about = ()->
|
||||
$document.scrollToElementAnimated(about_id)
|
||||
]
|
|
@ -1,21 +0,0 @@
|
|||
@app.controller 'AdminSessionsController', [ '$scope', '$http', '$timeout', '$cookies', ($scope, $http, $timeout, $cookies)->
|
||||
url = '/admin/sessions'
|
||||
|
||||
$scope.login = ->
|
||||
$http
|
||||
url: url
|
||||
method: 'POST'
|
||||
data:
|
||||
username: $scope.username
|
||||
password: $scope.password
|
||||
.success (res)->
|
||||
if res.success
|
||||
urlback = $cookies.urlback || '/admin'
|
||||
window.location = urlback
|
||||
else
|
||||
$scope.password = ''
|
||||
$scope.error_msg = res.message
|
||||
$timeout ->
|
||||
$scope.error_msg = null
|
||||
, 5000
|
||||
]
|
|
@ -1,43 +0,0 @@
|
|||
@app.controller 'ArchivesController',[ '$scope', '$http', '$location', '$timeout', '$cookies', ($scope, $http, $location, $timeout, $cookies)->
|
||||
url = window.location.pathname + ".json"
|
||||
start_with = $cookies.start_with if window.location.pathname == $cookies.start_with_type
|
||||
$http
|
||||
url: url
|
||||
method: 'GET'
|
||||
params:
|
||||
start_with: start_with
|
||||
all: true
|
||||
.success (res)->
|
||||
$scope.update_start_with(res.start_with)
|
||||
$scope.posts = res.posts
|
||||
|
||||
$scope.no_more_flag = false
|
||||
$scope.loading_flag = false
|
||||
|
||||
$scope.load = ()->
|
||||
$scope.loading_flag = true
|
||||
$http(
|
||||
url: url
|
||||
method: 'GET'
|
||||
params:
|
||||
start_with: $scope.start_with
|
||||
type: $scope.type
|
||||
).success (res)->
|
||||
$scope.no_more_flag = true if res.posts.length == 0
|
||||
$scope.update_start_with(res.start_with)
|
||||
$scope.posts = $scope.posts.concat(res.posts)
|
||||
$timeout ->
|
||||
$scope.loading_flag = false
|
||||
, 500
|
||||
$timeout ->
|
||||
$scope.no_more_flag = false
|
||||
, 3000
|
||||
|
||||
$scope.visit = (id)->
|
||||
"/blogs/" + id
|
||||
|
||||
$scope.update_start_with = (start_with)->
|
||||
$scope.start_with = start_with
|
||||
$cookies.start_with_type = window.location.pathname
|
||||
$cookies.start_with = start_with
|
||||
]
|
|
@ -1,35 +0,0 @@
|
|||
@app.controller 'CommentsController', ['$scope', '$http', '$location', '$timeout', '$cookies', ($scope, $http, $location, $timeout, $cookies)->
|
||||
url = window.location.pathname + "/comments.json"
|
||||
|
||||
$scope.name = $cookies.name
|
||||
$scope.email = $cookies.email
|
||||
|
||||
$http.get(url).success (data)->
|
||||
$scope.comments = data
|
||||
|
||||
$scope.publish_success = null
|
||||
|
||||
$scope.submit = ->
|
||||
$scope.submitting = true
|
||||
$cookies.name = $scope.name
|
||||
$cookies.email = $scope.email
|
||||
comment = { content: $scope.content, name: $scope.name, email: $scope.email }
|
||||
$http.post(url, comment)
|
||||
.success (res)->
|
||||
if res.success
|
||||
$scope.publish_success = true
|
||||
$scope.content = ''
|
||||
$scope.comments.unshift(res.data)
|
||||
else
|
||||
$scope.publish_success = false
|
||||
$scope.publish_fail_msg = res.message
|
||||
.error (data, status)->
|
||||
$scope.publish_success = false
|
||||
$scope.publish_fail_msg = 'Network Error, Retry for a moment, Status Code: ' + status
|
||||
.finally ->
|
||||
$scope.submitting = false
|
||||
$scope.timeout = $timeout ->
|
||||
$timeout.cancel($scope.timeout)
|
||||
$scope.publish_success = null
|
||||
, 5*1000
|
||||
]
|
|
@ -1,9 +0,0 @@
|
|||
@app.directive 'ngInitial', ->
|
||||
restrict: 'A',
|
||||
controller: [
|
||||
'$scope', '$element', '$attrs', '$parse', ($scope, $element, $attrs, $parse)->
|
||||
val = $attrs.ngInitial || $attrs.value || $attrs.$$element.text()
|
||||
getter = $parse($attrs.ngModel)
|
||||
setter = getter.assign
|
||||
setter($scope, val)
|
||||
]
|
|
@ -1,38 +0,0 @@
|
|||
@app.controller 'LikesController', ['$scope', '$http', '$location', '$cookies', ($scope, $http, $location, $cookies)->
|
||||
url = window.location.pathname + "/likes"
|
||||
|
||||
$http.get url
|
||||
.success (res)->
|
||||
$scope.count = res.count
|
||||
|
||||
$scope.like = $cookies.like
|
||||
|
||||
if $scope.like
|
||||
$http
|
||||
url: window.location.pathname + "/likes/#{$scope.like}/is_liked"
|
||||
method: 'GET'
|
||||
.success (res)->
|
||||
if res == true
|
||||
$scope.is_liked = true
|
||||
else
|
||||
$scope.is_liked = false
|
||||
else
|
||||
$scope.is_liked = false
|
||||
|
||||
$scope.submit = ->
|
||||
$http.post url
|
||||
.success (res)->
|
||||
if res.success
|
||||
$scope.like = $cookies.like = res.id
|
||||
$scope.count = res.count
|
||||
$scope.is_liked = true
|
||||
|
||||
$scope.cancel = ->
|
||||
$http.delete url + "/" + $scope.like
|
||||
.success (res)->
|
||||
$scope.count = res.count
|
||||
$scope.is_liked = false
|
||||
# anyway, clear cookie
|
||||
delete $cookies["like"]
|
||||
$scope.like = null
|
||||
]
|
|
@ -1,4 +0,0 @@
|
|||
@app.controller 'QRCodesController', [ '$scope', ($scope)->
|
||||
$scope.show = ->
|
||||
$scope.qrcode = ! $scope.qrcode
|
||||
]
|
|
@ -1,10 +0,0 @@
|
|||
@app.controller 'SubscribesController', [ '$scope', '$http', ($scope, $http)->
|
||||
$scope.cancel = ()->
|
||||
$http
|
||||
url: '/subscribes/cancel'
|
||||
method: 'POST'
|
||||
params:
|
||||
email: $scope.email
|
||||
.success (res)->
|
||||
window.location = '/'
|
||||
]
|
|
@ -1,9 +1,10 @@
|
|||
//= require jquery
|
||||
//= require jquery_ujs
|
||||
//= require turbolinks
|
||||
//= require foundation
|
||||
//= require angularjs
|
||||
//= require 'jquery.html5-fileupload'
|
||||
//= require_tree .
|
||||
|
||||
|
||||
$(function(){ $(document).foundation(); });
|
||||
$(document).on('turbolinks:load', function(){
|
||||
$(document).foundation();
|
||||
});
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
$(document).ready ()->
|
||||
$(document).on 'turbolinks:load', ->
|
||||
$('#qrcode-link').click (event)->
|
||||
event.preventDefault()
|
||||
$('.social-share').toggle()
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
.ng-dirty .ng-invalid, .ng-dirty .ng-required {
|
||||
border: 1px solid #FF7A7A !important;
|
||||
}
|
|
@ -9,9 +9,14 @@
|
|||
@import 'blogs';
|
||||
@import 'head';
|
||||
@import 'qrcodes';
|
||||
@import 'angularjs';
|
||||
@import 'comments';
|
||||
@import 'highlight';
|
||||
@import 'footer';
|
||||
@import 'like_and_weixin';
|
||||
@import 'admin/*';
|
||||
|
||||
.turbolinks-progress-bar {
|
||||
height: 2px;
|
||||
background-color: red;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
class ArchivesController < ApplicationController
|
||||
def index
|
||||
@posts = Post.order(created_at: :desc)
|
||||
@posts = Post.order(created_at: :desc).page(params[:page]).per(3)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -19,3 +19,4 @@
|
|||
i.fi-heart
|
||||
span
|
||||
= post.liked_count
|
||||
= paginate @posts
|
||||
|
|
|
@ -6,9 +6,9 @@ html
|
|||
= yield(:meta)
|
||||
title
|
||||
= content_for?(:title) ? yield(:title) + " | #{ENV['SITE_NAME']}" : ENV['SITE_NAME']
|
||||
= stylesheet_link_tag "application", media: 'all'
|
||||
= stylesheet_link_tag "application", 'data-turbolinks-track' => "reload"
|
||||
= favicon_link_tag 'favicon.png', type: 'image/png'
|
||||
= javascript_include_tag "application"
|
||||
= javascript_include_tag "application", 'data-turbolinks-track' => "reload"
|
||||
= csrf_meta_tags
|
||||
body data-whatinput="mouse"
|
||||
- if content_for?(:main)
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
development:
|
||||
adapter: postgresql
|
||||
host: localhost
|
||||
encoding: unicode
|
||||
database: wblog_development
|
||||
pool: 5
|
||||
|
||||
test:
|
||||
adapter: postgresql
|
||||
host: localhost
|
||||
encoding: unicode
|
||||
database: wblog_test
|
||||
pool: 5
|
||||
|
||||
production:
|
||||
adapter: postgresql
|
||||
host: localhost
|
||||
encoding: unicode
|
||||
database: wblog_production
|
||||
pool: 5
|
|
@ -1,29 +0,0 @@
|
|||
development:
|
||||
clients:
|
||||
default:
|
||||
database: w_blog_development
|
||||
hosts:
|
||||
- localhost:27017
|
||||
options:
|
||||
|
||||
production:
|
||||
clients:
|
||||
default:
|
||||
database: w_blog_production
|
||||
hosts:
|
||||
- localhost:27017
|
||||
options:
|
||||
|
||||
test:
|
||||
clients:
|
||||
default:
|
||||
database: w_blog_test
|
||||
hosts:
|
||||
- localhost:27017
|
||||
options:
|
||||
read:
|
||||
mode: :primary
|
||||
# In the test environment we lower the retries and retry interval to
|
||||
# low amounts for fast failures.
|
||||
max_retries: 1
|
||||
retry_interval: 0
|
|
@ -0,0 +1,8 @@
|
|||
threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 }.to_i
|
||||
threads threads_count, threads_count
|
||||
|
||||
port ENV.fetch("PORT") { 3000 }
|
||||
|
||||
environment ENV.fetch("RAILS_ENV") { "development" }
|
||||
|
||||
plugin :tmp_restart
|
Loading…
Reference in New Issue