summaryrefslogtreecommitdiffstats
path: root/js/directive
diff options
context:
space:
mode:
authorBernhard Posselt <dev@bernhard-posselt.com>2014-09-16 16:24:20 +0200
committerBernhard Posselt <dev@bernhard-posselt.com>2014-09-16 16:24:20 +0200
commit9e36ef31f9bf16d43326fd047619ada5ff16e072 (patch)
treee228816adedacfed87eb08e8bc86658536cbbe86 /js/directive
parent6a7ac3d9da3dea4130eb08a07a0a0603418d54ab (diff)
parent21728afff571adfc508cf5fa473d094946ef188f (diff)
merge
Diffstat (limited to 'js/directive')
-rw-r--r--js/directive/AppNavigationEntryUtils.js37
-rw-r--r--js/directive/NewsAudio.js40
-rw-r--r--js/directive/NewsAutoFocus.js24
-rw-r--r--js/directive/NewsBindUnsafeHtml.js18
-rw-r--r--js/directive/NewsDraggable.js30
-rw-r--r--js/directive/NewsDroppable.js34
-rw-r--r--js/directive/NewsFocus.js22
-rw-r--r--js/directive/NewsPullToRefresh.js36
-rw-r--r--js/directive/NewsReadFile.js30
-rw-r--r--js/directive/NewsScroll.js120
-rw-r--r--js/directive/NewsStopPropagation.js20
-rw-r--r--js/directive/NewsTimeout.js35
-rw-r--r--js/directive/NewsTitleUnreadCount.js32
-rw-r--r--js/directive/NewsTriggerClick.js19
14 files changed, 497 insertions, 0 deletions
diff --git a/js/directive/AppNavigationEntryUtils.js b/js/directive/AppNavigationEntryUtils.js
new file mode 100644
index 000000000..c96589a6a
--- /dev/null
+++ b/js/directive/AppNavigationEntryUtils.js
@@ -0,0 +1,37 @@
+/**
+ * ownCloud - News
+ *
+ * This file is licensed under the Affero General Public License version 3 or
+ * later. See the COPYING file.
+ *
+ * @author Bernhard Posselt <dev@bernhard-posselt.com>
+ * @copyright Bernhard Posselt 2014
+ */
+app.run(function ($document, $rootScope) {
+ 'use strict';
+ $document.click(function (event) {
+ $rootScope.$broadcast('documentClicked', event);
+ });
+});
+
+app.directive('appNavigationEntryUtils', function () {
+ 'use strict';
+ return {
+ restrict: 'C',
+ link: function (scope, elm) {
+ var menu = elm.siblings('.app-navigation-entry-menu');
+ var button = $(elm)
+ .find('.app-navigation-entry-utils-menu-button button');
+
+ button.click(function () {
+ menu.toggleClass('open');
+ });
+
+ scope.$on('documentClicked', function (scope, event) {
+ if (event.target !== button[0]) {
+ menu.removeClass('open');
+ }
+ });
+ }
+ };
+}); \ No newline at end of file
diff --git a/js/directive/NewsAudio.js b/js/directive/NewsAudio.js
new file mode 100644
index 000000000..422f5ff19
--- /dev/null
+++ b/js/directive/NewsAudio.js
@@ -0,0 +1,40 @@
+/**
+ * ownCloud - News
+ *
+ * This file is licensed under the Affero General Public License version 3 or
+ * later. See the COPYING file.
+ *
+ * @author Bernhard Posselt <dev@bernhard-posselt.com>
+ * @copyright Bernhard Posselt 2014
+ */
+app.directive('newsAudio', function () {
+ 'use strict';
+ return {
+ restrict: 'E',
+ scope: {
+ src: '@',
+ type: '@'
+ },
+ transclude: true,
+ template: '' +
+ '<audio controls="controls" preload="none" ng-hide="cantPlay()">' +
+ '<source ng-src="{{ src|trustUrl }}">' +
+ '</audio>' +
+ '<a ng-href="{{ src|trustUrl }}" class="button" ng-show="cantPlay()" ' +
+ 'ng-transclude></a>',
+ link: function (scope, elm) {
+ var source = elm.children().children('source')[0];
+ var cantPlay = false;
+
+ source.addEventListener('error', function () {
+ scope.$apply(function () {
+ cantPlay = true;
+ });
+ });
+
+ scope.cantPlay = function () {
+ return cantPlay;
+ };
+ }
+ };
+}); \ No newline at end of file
diff --git a/js/directive/NewsAutoFocus.js b/js/directive/NewsAutoFocus.js
new file mode 100644
index 000000000..422df4d78
--- /dev/null
+++ b/js/directive/NewsAutoFocus.js
@@ -0,0 +1,24 @@
+/**
+ * ownCloud - News
+ *
+ * This file is licensed under the Affero General Public License version 3 or
+ * later. See the COPYING file.
+ *
+ * @author Bernhard Posselt <dev@bernhard-posselt.com>
+ * @copyright Bernhard Posselt 2014
+ */
+app.directive('newsAutoFocus', function ($timeout) {
+ 'use strict';
+ return function (scope, elem, attrs) {
+ var toFocus = elem;
+
+ if (attrs.newsAutoFocus) {
+ toFocus = $(attrs.newsAutoFocus);
+ }
+
+ // to combat $digest already in process error when route changes
+ $timeout(function () {
+ toFocus.focus();
+ }, 0);
+ };
+}); \ No newline at end of file
diff --git a/js/directive/NewsBindUnsafeHtml.js b/js/directive/NewsBindUnsafeHtml.js
new file mode 100644
index 000000000..5d8cadf85
--- /dev/null
+++ b/js/directive/NewsBindUnsafeHtml.js
@@ -0,0 +1,18 @@
+/**
+ * ownCloud - News
+ *
+ * This file is licensed under the Affero General Public License version 3 or
+ * later. See the COPYING file.
+ *
+ * @author Bernhard Posselt <dev@bernhard-posselt.com>
+ * @copyright Bernhard Posselt 2014
+ */
+app.directive('newsBindHtmlUnsafe', function () {
+ 'use strict';
+
+ return function (scope, elem, attr) {
+ scope.$watch(attr.newsBindHtmlUnsafe, function () {
+ elem.html(scope.$eval(attr.newsBindHtmlUnsafe));
+ });
+ };
+}); \ No newline at end of file
diff --git a/js/directive/NewsDraggable.js b/js/directive/NewsDraggable.js
new file mode 100644
index 000000000..2d365e06c
--- /dev/null
+++ b/js/directive/NewsDraggable.js
@@ -0,0 +1,30 @@
+/**
+ * ownCloud - News
+ *
+ * This file is licensed under the Affero General Public License version 3 or
+ * later. See the COPYING file.
+ *
+ * @author Bernhard Posselt <dev@bernhard-posselt.com>
+ * @copyright Bernhard Posselt 2014
+ */
+app.directive('newsDraggable', function () {
+ 'use strict';
+
+ return function (scope, elem, attr) {
+ var options = scope.$eval(attr.newsDraggable);
+
+ if (angular.isDefined(options)) {
+ elem.draggable(options);
+ } else {
+ elem.draggable();
+ }
+
+ attr.$observe('newsDraggableDisable', function (value) {
+ if (value === 'true') {
+ elem.draggable('disable');
+ } else {
+ elem.draggable('enable');
+ }
+ });
+ };
+}); \ No newline at end of file
diff --git a/js/directive/NewsDroppable.js b/js/directive/NewsDroppable.js
new file mode 100644
index 000000000..2808dc6a4
--- /dev/null
+++ b/js/directive/NewsDroppable.js
@@ -0,0 +1,34 @@
+/**
+ * ownCloud - News
+ *
+ * This file is licensed under the Affero General Public License version 3 or
+ * later. See the COPYING file.
+ *
+ * @author Bernhard Posselt <dev@bernhard-posselt.com>
+ * @copyright Bernhard Posselt 2014
+ */
+app.directive('newsDroppable', function ($rootScope) {
+ 'use strict';
+
+ return function (scope, elem, attr) {
+ var details = {
+ accept: '.feed',
+ hoverClass: 'drag-and-drop',
+ greedy: true,
+ drop: function (event, ui) {
+
+ $('.drag-and-drop').removeClass('drag-and-drop');
+
+ var data = {
+ folderId: parseInt(elem.data('id'), 10),
+ feedId: parseInt($(ui.draggable).data('id'), 10)
+ };
+
+ $rootScope.$broadcast('moveFeedToFolder', data);
+ scope.$apply(attr.droppable);
+ }
+ };
+
+ elem.droppable(details);
+ };
+}); \ No newline at end of file
diff --git a/js/directive/NewsFocus.js b/js/directive/NewsFocus.js
new file mode 100644
index 000000000..5c83db4f5
--- /dev/null
+++ b/js/directive/NewsFocus.js
@@ -0,0 +1,22 @@
+/**
+ * ownCloud - News
+ *
+ * This file is licensed under the Affero General Public License version 3 or
+ * later. See the COPYING file.
+ *
+ * @author Bernhard Posselt <dev@bernhard-posselt.com>
+ * @copyright Bernhard Posselt 2014
+ */
+app.directive('newsFocus', function ($timeout, $interpolate) {
+ 'use strict';
+
+ return function (scope, elem, attrs) {
+ elem.click(function () {
+ var toReadd = $($interpolate(attrs.newsFocus)(scope));
+ $timeout(function () {
+ toReadd.focus();
+ }, 500);
+ });
+ };
+
+}); \ No newline at end of file
diff --git a/js/directive/NewsPullToRefresh.js b/js/directive/NewsPullToRefresh.js
new file mode 100644
index 000000000..7938a8f63
--- /dev/null
+++ b/js/directive/NewsPullToRefresh.js
@@ -0,0 +1,36 @@
+/**
+ * ownCloud - News
+ *
+ * This file is licensed under the Affero General Public License version 3 or
+ * later. See the COPYING file.
+ *
+ * @author Bernhard Posselt <dev@bernhard-posselt.com>
+ * @copyright Bernhard Posselt 2014
+ */
+app.directive('newsPullToRefresh', function ($route, $rootScope) {
+ 'use strict';
+
+ var scrolled = false;
+
+ return {
+ restrict: 'A',
+ scope: {
+ 'newsTimeout': '&'
+ },
+ link: function (scope, element) {
+
+ // change in the route means the content is refreshed
+ // so reset the var
+ $rootScope.$on('$routeChangeStart', function () {
+ scrolled = false;
+ });
+
+ element.on('scroll', function () {
+ if (element.scrollTop() === 0 && scrolled) {
+ $route.reload();
+ }
+ scrolled = true;
+ });
+ }
+ };
+}); \ No newline at end of file
diff --git a/js/directive/NewsReadFile.js b/js/directive/NewsReadFile.js
new file mode 100644
index 000000000..9b06d8479
--- /dev/null
+++ b/js/directive/NewsReadFile.js
@@ -0,0 +1,30 @@
+/**
+ * ownCloud - News
+ *
+ * This file is licensed under the Affero General Public License version 3 or
+ * later. See the COPYING file.
+ *
+ * @author Bernhard Posselt <dev@bernhard-posselt.com>
+ * @copyright Bernhard Posselt 2014
+ */
+app.directive('newsReadFile', function () {
+ 'use strict';
+
+ return function (scope, elem, attr) {
+
+ elem.change(function () {
+
+ var file = elem[0].files[0];
+ var reader = new FileReader();
+
+ reader.onload = function (event) {
+ // FIXME: is there a more flexible solution where we dont have
+ // to bind the file to scope?
+ scope.$fileContent = event.target.result;
+ scope.$apply(attr.newsReadFile);
+ };
+
+ reader.readAsText(file);
+ });
+ };
+}); \ No newline at end of file
diff --git a/js/directive/NewsScroll.js b/js/directive/NewsScroll.js
new file mode 100644
index 000000000..c0b345163
--- /dev/null
+++ b/js/directive/NewsScroll.js
@@ -0,0 +1,120 @@
+/**
+ * ownCloud - News
+ *
+ * This file is licensed under the Affero General Public License version 3 or
+ * later. See the COPYING file.
+ *
+ * @author Bernhard Posselt <dev@bernhard-posselt.com>
+ * @copyright Bernhard Posselt 2014
+ */
+app.directive('newsScroll', function ($timeout) {
+ 'use strict';
+ var timer;
+
+ // autopaging
+ var autoPage = function (limit, elem, scope) {
+ var counter = 0;
+ var articles = elem.find('.item');
+
+ for (var i = articles.length - 1; i >= 0; i -= 1) {
+ var item = $(articles[i]);
+
+
+ // if the counter is higher than the size it means
+ // that it didnt break to auto page yet and that
+ // there are more items, so break
+ if (counter >= limit) {
+ break;
+ }
+
+ // this is only reached when the item is not is
+ // below the top and we didnt hit the factor yet so
+ // autopage and break
+ if (item.position().top < 0) {
+ scope.$apply(scope.newsScrollAutoPage);
+ break;
+ }
+
+ counter += 1;
+ }
+ };
+
+ // mark read
+ var markRead = function (enabled, elem, scope) {
+ if (enabled) {
+ var ids = [];
+ var articles = elem.find('.item:not(.read)');
+
+ articles.each(function(index, article) {
+ var item = $(article);
+
+ if (item.position().top <= -50) {
+ ids.push(parseInt(item.data('id'), 10));
+ } else {
+ return false;
+ }
+ });
+
+ scope.itemIds = ids;
+ scope.$apply(scope.newsScrollMarkRead);
+ }
+ };
+
+ return {
+ restrict: 'A',
+ scope: {
+ 'newsScroll': '@',
+ 'newsScrollAutoPage': '&',
+ 'newsScrollMarkRead': '&',
+ 'newsScrollEnabledMarkRead': '=',
+ 'newsScrollMarkReadTimeout': '@', // optional, defaults to 1 second
+ 'newsScrollTimeout': '@', // optional, defaults to 1 second
+ 'newsScrollAutoPageWhenLeft': '@' // optional, defaults to 50
+ },
+ link: function (scope, elem) {
+ var allowScroll = true;
+ var scrollArea = elem;
+
+ if (scope.newsScroll) {
+ scrollArea = $(scope.newsScroll);
+ }
+
+ var scrollTimeout = scope.newsScrollTimeout || 1;
+ var markReadTimeout = scope.newsScrollMarkReadTimeout || 1;
+ var autoPageLimit = scope.newsScrollAutoPageWhenLeft || 50;
+
+ var scrollHandler = function () {
+ // allow only one scroll event to trigger every 300ms
+ if (allowScroll) {
+ allowScroll = false;
+
+ $timeout(function () {
+ allowScroll = true;
+ }, scrollTimeout*100);
+
+ autoPage(autoPageLimit, elem, scope);
+
+ // dont stack mark read requests
+ if (timer) {
+ $timeout.cancel(timer);
+ }
+
+ // allow user to undo accidental scroll
+ timer = $timeout(function () {
+ markRead(scope.newsScrollEnabledMarkRead,
+ elem,
+ scope);
+ timer = undefined;
+ }, markReadTimeout*1000);
+ }
+ };
+
+ scrollArea.on('scroll', scrollHandler);
+
+ // remove scroll handler if element is destroyed
+ scope.$on('$destroy', function () {
+ scrollArea.off('scroll', scrollHandler);
+ });
+ }
+ };
+}); \ No newline at end of file
diff --git a/js/directive/NewsStopPropagation.js b/js/directive/NewsStopPropagation.js
new file mode 100644
index 000000000..79954bfa0
--- /dev/null
+++ b/js/directive/NewsStopPropagation.js
@@ -0,0 +1,20 @@
+/**
+ * ownCloud - News
+ *
+ * This file is licensed under the Affero General Public License version 3 or
+ * later. See the COPYING file.
+ *
+ * @author Bernhard Posselt <dev@bernhard-posselt.com>
+ * @copyright Bernhard Posselt 2014
+ */
+app.directive('newsStopPropagation', function () {
+ 'use strict';
+ return {
+ restrict: 'A',
+ link: function (scope, element) {
+ element.bind('click', function (event) {
+ event.stopPropagation();
+ });
+ }
+ };
+}); \ No newline at end of file
diff --git a/js/directive/NewsTimeout.js b/js/directive/NewsTimeout.js
new file mode 100644
index 000000000..43c6290a3
--- /dev/null
+++ b/js/directive/NewsTimeout.js
@@ -0,0 +1,35 @@
+/**
+ * ownCloud - News
+ *
+ * This file is licensed under the Affero General Public License version 3 or
+ * later. See the COPYING file.
+ *
+ * @author Bernhard Posselt <dev@bernhard-posselt.com>
+ * @copyright Bernhard Posselt 2014
+ */
+app.directive('newsTimeout', function ($timeout, $rootScope) {
+ 'use strict';
+
+ return {
+ restrict: 'A',
+ scope: {
+ 'newsTimeout': '&'
+ },
+ link: function (scope, element) {
+ var seconds = 7;
+ var timer = $timeout(scope.newsTimeout, seconds * 1000);
+
+ // remove timeout if element is being removed by
+ // for instance clicking on the x button
+ scope.$on('$destroy', function () {
+ $timeout.cancel(timer);
+ });
+
+ // also delete the entry if undo is ignored and the url
+ // is changed
+ $rootScope.$on('$locationChangeStart', function () {
+ element.remove();
+ });
+ }
+ };
+}); \ No newline at end of file
diff --git a/js/directive/NewsTitleUnreadCount.js b/js/directive/NewsTitleUnreadCount.js
new file mode 100644
index 000000000..0866b4b72
--- /dev/null
+++ b/js/directive/NewsTitleUnreadCount.js
@@ -0,0 +1,32 @@
+/**
+ * ownCloud - News
+ *
+ * This file is licensed under the Affero General Public License version 3 or
+ * later. See the COPYING file.
+ *
+ * @author Bernhard Posselt <dev@bernhard-posselt.com>
+ * @copyright Bernhard Posselt 2014
+ */
+app.directive('newsTitleUnreadCount', function ($window) {
+ 'use strict';
+
+ var baseTitle = $window.document.title;
+
+ return {
+ restrict: 'E',
+ scope: {
+ unreadCount: '@'
+ },
+ link: function (scope, elem, attrs) {
+ attrs.$observe('unreadCount', function (value) {
+ var titles = baseTitle.split('-');
+
+ if (value !== '0') {
+ $window.document.title = titles[0] +
+ '(' + value + ') - ' + titles[1];
+ }
+ });
+ }
+ };
+
+}); \ No newline at end of file
diff --git a/js/directive/NewsTriggerClick.js b/js/directive/NewsTriggerClick.js
new file mode 100644
index 000000000..a0a3f2904
--- /dev/null
+++ b/js/directive/NewsTriggerClick.js
@@ -0,0 +1,19 @@
+/**
+ * ownCloud - News
+ *
+ * This file is licensed under the Affero General Public License version 3 or
+ * later. See the COPYING file.
+ *
+ * @author Bernhard Posselt <dev@bernhard-posselt.com>
+ * @copyright Bernhard Posselt 2014
+ */
+app.directive('newsTriggerClick', function () {
+ 'use strict';
+
+ return function (scope, elm, attr) {
+ elm.click(function () {
+ $(attr.newsTriggerClick).trigger('click');
+ });
+ };
+
+}); \ No newline at end of file