removed old files from the previous news version

This commit is contained in:
Bernhard Posselt 2013-03-23 15:28:35 +01:00
Родитель 8f637cfb85
Коммит 503817875b
44 изменённых файлов: 0 добавлений и 2436 удалений

Просмотреть файл

@ -1,102 +0,0 @@
###
# ownCloud news app
#
# @author Alessandro Cosentino
# @author Bernhard Posselt
# Copyright (c) 2012 - Alessandro Cosentino <cosenal@gmail.com>
# Copyright (c) 2012 - Bernhard Posselt <nukeawhale@gmail.com>
#
# This file is licensed under the Affero General Public License version 3 or
# later.
#
# See the COPYING-README file
#
###
module.exports = (grunt) ->
grunt.loadNpmTasks('grunt-contrib-coffee')
grunt.loadNpmTasks('grunt-contrib-concat')
grunt.loadNpmTasks('grunt-contrib-watch')
grunt.loadNpmTasks('grunt-coffeelint')
grunt.loadNpmTasks('gruntacular');
grunt.initConfig
meta:
pkg: grunt.file.readJSON('package.json')
version: '<%= meta.pkg.version %>'
banner: '/**\n' +
' * <%= meta.pkg.description %> - v<%= meta.version %>\n' +
' *\n' +
'<% _.forEach(meta.pkg.contributors, function(contributor){ %>' +
' * Copyright (c) <%= grunt.template.today("yyyy") %> - ' +
'<%= contributor.name %> <<%= contributor.email %>>\n' +
'<% }) %>' +
' *\n' +
' * This file is licensed under the Affero General Public License version 3 or later.\n' +
' * See the COPYING-README file\n' +
' *\n' +
' */'
prefix: '(function(angular, $, OC, oc_requesttoken){'
suffix: '})(window.angular, jQuery, OC, oc_requesttoken);'
build: 'build/'
production: '../js/'
concat:
app:
options:
banner: '<%= meta.banner %>\n'
src: '<%= meta.build %>main.js'
dest: '<%= meta.production %>app.js'
owncloud:
src: ['lib/owncloud.coffee', 'lib/services/*.coffee']
dest: '<%= meta.build %>owncloud.coffee'
news:
src: [
'app.coffee'
'services/*.coffee'
'controllers/*.coffee'
'directives/*.coffee'
'filters/*.coffee'
]
dest: '<%= meta.build %>news.coffee'
coffee:
compile:
files:
'<%= meta.build %>main.js': [
'<%= meta.build %>owncloud.coffee'
'<%= meta.build %>news.coffee'
]
coffeelint:
app: [
'app.coffee'
'services/*.coffee'
'controllers/*.coffee'
'directives/*.coffee'
'filters/*.coffee'
'lib/**/*.coffee'
]
coffeelintOptions:
'no_tabs':
'level': 'ignore'
'indentation':
'level': 'ignore'
watch:
app:
files: './**/*.coffee',
tasks: 'compile'
grunt.registerTask('run', ['watch'])
grunt.registerTask('lint', ['coffeelint'])
grunt.registerTask('compile', [
#'coffeelint'
'concat:owncloud'
'concat:news'
'coffee'
'concat:app'
]
)

Просмотреть файл

@ -1,16 +0,0 @@
all: watch
deps:
cd $(CURDIR)
npm install --save-dev
watch: compile
$(CURDIR)/node_modules/.bin/grunt --config $(CURDIR)/Gruntfile.coffee run
compile:
mkdir -p $(CURDIR)/build
$(CURDIR)/node_modules/.bin/grunt --config $(CURDIR)/Gruntfile.coffee compile
clean:
rm -rf $(CURDIR)/build

Просмотреть файл

@ -1,42 +0,0 @@
###
# ownCloud news app
#
# @author Alessandro Cosentino
# @author Bernhard Posselt
# Copyright (c) 2012 - Alessandro Cosentino <cosenal@gmail.com>
# Copyright (c) 2012 - Bernhard Posselt <nukeawhale@gmail.com>
#
# This file is licensed under the Affero General Public License version 3 or
# later.
#
# See the COPYING-README file
#
###
app = angular.module('News', ['ui']).config ($provide) ->
# enter your config values in here
config =
MarkReadTimeout: 500
ScrollTimeout: 500
initialLoadedItemsNr: 20
FeedUpdateInterval: 6000000
$provide.value('Config', config)
app.run ['PersistenceNews', (PersistenceNews) ->
PersistenceNews.loadInitial()
]
$(document).ready ->
# this is used to forces browser to reload content after refreshing
# and thus clearing the scroll cache
$(this).keyup (e) ->
if (e.which == 116) || (e.which == 82 && e.ctrlKey)
document.location.reload(true)
return false
# click on upload button should trigger the file input
$('#browselink').click ->
$('#file_upload_start').trigger('click')

Просмотреть файл

@ -1,18 +0,0 @@
###
# ownCloud news app
#
# @author Alessandro Cosentino
# @author Bernhard Posselt
# Copyright (c) 2012 - Alessandro Cosentino <cosenal@gmail.com>
# Copyright (c) 2012 - Bernhard Posselt <nukeawhale@gmail.com>
#
# This file is licensed under the Affero General Public License version 3 or
# later.
#
# See the COPYING-README file
#
###
angular.module('News').factory 'Controller', ->
class Controller
constructor: () ->

Просмотреть файл

@ -1,43 +0,0 @@
###
# ownCloud news app
#
# @author Alessandro Cosentino
# @author Bernhard Posselt
# Copyright (c) 2012 - Alessandro Cosentino <cosenal@gmail.com>
# Copyright (c) 2012 - Bernhard Posselt <nukeawhale@gmail.com>
#
# This file is licensed under the Affero General Public License version 3 or
# later.
#
# See the COPYING-README file
#
###
angular.module('News').controller 'SettingsController',
['_SettingsController', '$scope', '$rootScope', 'PersistenceNews', 'OPMLParser', 'FeedModel',
(_SettingsController, $scope, $rootScope, PersistenceNews, OPMLParser, FeedModel) ->
return new _SettingsController($scope, $rootScope, PersistenceNews,
OPMLParser, FeedModel)
]
angular.module('News').controller 'ItemController',
['_ItemController', '$scope', 'ItemModel', 'ActiveFeed', 'PersistenceNews', 'FeedModel',
'StarredCount', 'GarbageRegistry', 'ShowAll', 'Loading', '$rootScope', 'FeedType',
(_ItemController, $scope, ItemModel, ActiveFeed, PersistenceNews, FeedModel,
StarredCount, GarbageRegistry, ShowAll, Loading, $rootScope, FeedType) ->
return new _ItemController($scope, ItemModel, ActiveFeed, PersistenceNews
FeedModel, StarredCount, GarbageRegistry,
ShowAll, Loading, $rootScope, FeedType)
]
angular.module('News').controller 'FeedController',
['_FeedController', '$scope', 'FeedModel', 'FeedType', 'FolderModel', 'ActiveFeed', 'PersistenceNews',
'StarredCount', 'ShowAll', 'ItemModel', 'GarbageRegistry', '$rootScope', 'Loading',
'Config',
(_FeedController, $scope, FeedModel, FeedType, FolderModel, ActiveFeed, PersistenceNews
StarredCount, ShowAll, ItemModel, GarbageRegistry, $rootScope, Loading, Config) ->
return new _FeedController($scope, FeedModel, FolderModel, FeedType,
ActiveFeed, PersistenceNews, StarredCount, ShowAll,
ItemModel, GarbageRegistry, $rootScope, Loading,
Config)
]

Просмотреть файл

@ -1,281 +0,0 @@
###
# ownCloud news app
#
# @author Alessandro Cosentino
# @author Bernhard Posselt
# Copyright (c) 2012 - Alessandro Cosentino <cosenal@gmail.com>
# Copyright (c) 2012 - Bernhard Posselt <nukeawhale@gmail.com>
#
# This file is licensed under the Affero General Public License version 3 or
# later.
#
# See the COPYING-README file
#
###
angular.module('News').factory '_FeedController', ['Controller', (Controller) ->
class FeedController extends Controller
constructor: (@$scope, @feedModel, @folderModel, @feedType, @activeFeed,
@persistence, @starredCount, @showAll, @itemModel,
@garbageRegistry, @$rootScope, @loading, @config) ->
@showSubscriptions = true
@$scope.feeds = @feedModel.getItems()
@$scope.folders = @folderModel.getItems()
@$scope.feedType = @feedType
@$scope.getShowAll = =>
return @showAll.showAll
@$scope.setShowAll = (value) =>
@showAll.showAll = value
@persistence.showAll(value)
@$rootScope.$broadcast('triggerHideRead')
@$scope.addFeed = (url, folder) =>
@$scope.feedEmptyError = false
@$scope.feedExistsError = false
@$scope.feedError = false
if url == undefined or url.trim() == ''
@$scope.feedEmptyError = true
else
url = url.trim()
for feed in @feedModel.getItems()
if url == feed.url # FIXME: can we really compare this
@$scope.feedExistsError = true
if not (@$scope.feedEmptyError or @$scope.feedExistsError)
if folder == undefined
folderId = 0
else
folderId = folder.id
@$scope.adding = true
onSuccess = =>
@$scope.feedUrl = ''
@$scope.adding = false
onError = =>
@$scope.feedError = true
@$scope.adding = false
@persistence.createFeed(url, folderId, onSuccess, onError)
@$scope.addFolder = (name) =>
@$scope.folderEmptyError = false
@$scope.folderExistsError = false
if name == undefined or name.trim() == ''
@$scope.folderEmptyError = true
else
name = name.trim()
for folder in @folderModel.getItems()
if name.toLowerCase() == folder.name.toLowerCase()
@$scope.folderExistsError = true
if not (@$scope.folderEmptyError or @$scope.folderExistsError)
@addingFolder = true
onSuccess = =>
@$scope.folderName = ''
@addingFolder = false
@persistence.createFolder(name, onSuccess)
@$scope.toggleFolder = (folderId) =>
folder = @folderModel.getItemById(folderId)
folder.open = !folder.open
@persistence.collapseFolder(folder.id, folder.open)
@$scope.isFeedActive = (type, id) =>
if type == @activeFeed.type && id == @activeFeed.id
return true
else
return false
@$scope.loadFeed = (type, id) =>
@loadFeed(type, id)
@$scope.getUnreadCount = (type, id) =>
count = @getUnreadCount(type, id)
if count > 999
return "999+"
else
return count
@$scope.renameFolder = ->
alert 'not implemented yet, needs better solution'
@$scope.triggerHideRead = =>
@triggerHideRead()
@$scope.isShown = (type, id) =>
switch type
when @feedType.Subscriptions then return @showSubscriptions
when @feedType.Starred then return @starredCount.count > 0
@$scope.delete = (type, id) =>
switch type
when @feedType.Folder
@folderModel.removeById(id)
@persistence.deleteFolder(id)
when @feedType.Feed
@feedModel.removeById(id)
@persistence.deleteFeed(id)
@$scope.markAllRead = (type, id) =>
switch type
when @feedType.Feed
for itemId, item of @itemModel.getItemsByTypeAndId(type, id)
item.isRead = true
feed = @feedModel.getItemById(id)
feed.unreadCount = 0
mostRecentItemId = @itemModel.getHighestId(type, id)
@persistence.setAllItemsRead(feed.id, mostRecentItemId)
when @feedType.Folder
for itemId, item of @itemModel.getItemsByTypeAndId(type, id)
item.isRead = true
for feedId in @itemModel.getFeedsOfFolderId(id)
feed = @feedModel.getItemById(feedId)
feed.unreadCount = 0
mostRecentItemId = @itemModel.getHighestId(type, feedId)
@persistence.setAllItemsRead(feedId, mostRecentItemId)
when @feedType.Subscriptions
for itemId, item of @itemModel.getItemsByTypeAndId(type, id)
item.isRead = true
for feed in @feedModel.getItems()
feed.unreadCount = 0
mostRecentItemId = @itemModel.getHighestId(type, feed.id)
@persistence.setAllItemsRead(feed.id, mostRecentItemId)
@$scope.$on 'triggerHideRead', =>
@itemModel.clearCache()
@triggerHideRead()
@loadFeed(activeFeed.type, activeFeed.id)
@$scope.$on 'loadFeed', (scope, params) =>
@loadFeed(params.type, params.id)
@$scope.$on 'moveFeedToFolder', (scope, params) =>
@moveFeedToFolder(params.feedId, params.folderId)
setInterval =>
@updateFeeds()
, @config.FeedUpdateInterval
updateFeeds: ->
for feed in @feedModel.getItems()
@persistence.updateFeed(feed.id)
moveFeedToFolder: (feedId, folderId) ->
feed = @feedModel.getItemById(feedId)
if feed.folderId != folderId
feed.folderId = folderId
@feedModel.markAccessed()
@persistence.moveFeedToFolder(feedId, folderId)
loadFeed: (type, id) ->
# to not go crazy with autopaging, clear the caches if we switch the
# type of the feed. if the caches only contain seperate feeds, the
# cache and autopage logic works fine. if the feed contains more than
# one
if type != @activeFeed.type or id != @activeFeed.id
if not (type == @feedType.Feed && @activeFeed.type == @feedType.Feed)
@itemModel.clearCache()
@activeFeed.id = id
@activeFeed.type = type
@$scope.triggerHideRead()
@persistence.loadFeed(type, id,
@itemModel.getHighestId(type, id),
@itemModel.getHighestTimestamp(type, id), @config.initialLoadedItemsNr)
triggerHideRead: () ->
preventParentFolder = 0
# feeds
for feed in @feedModel.getItems()
if @showAll.showAll == false && @getUnreadCount(@feedType.Feed, feed.id) == 0
# we dont hide the selected feed and folder. But we also dont hide
# the parent folder of the selcted feed
if @activeFeed.type == @feedType.Feed && @activeFeed.id == feed.id
feed.show = true
preventParentFolder = feed.folderId
else
feed.show = false
else
feed.show = true
# folders
for folder in @folderModel.getItems()
if @showAll.showAll == false && @getUnreadCount(@feedType.Folder, folder.id) == 0
# prevent hiding when childfeed is active
if (@activeFeed.type == @feedType.Folder && @activeFeed.id == folder.id) || preventParentFolder == folder.id
folder.show = true
else
folder.show = false
else
folder.show = true
# subscriptions
if @showAll.showAll == false && @getUnreadCount(@feedType.Subscriptions, 0) == 0
if @activeFeed.type == @feedType.Subscriptions
@showSubscriptions = true
else
@showSubscriptions = false
else
@showSubscriptions = true
# starred
if @showAll.showAll == false && @getUnreadCount(@feedType.Starred, 0) == 0
if @activeFeed.type == @feedType.Starred
@showStarred = true
else
@showStarred = false
else
@showStarred = true
@garbageRegistry.clear()
getUnreadCount: (type, id) ->
switch type
when @feedType.Feed
return @feedModel.getItemById(id).unreadCount
when @feedType.Folder
counter = 0
for feed in @feedModel.getItems()
if feed.folderId == id
counter += feed.unreadCount
return counter
when @feedType.Starred
return @starredCount.count
when @feedType.Subscriptions
counter = 0
for feed in @feedModel.getItems()
counter += feed.unreadCount
return counter
return FeedController
]

Просмотреть файл

@ -1,97 +0,0 @@
###
# ownCloud news app
#
# @author Alessandro Cosentino
# @author Bernhard Posselt
# Copyright (c) 2012 - Alessandro Cosentino <cosenal@gmail.com>
# Copyright (c) 2012 - Bernhard Posselt <nukeawhale@gmail.com>
#
# This file is licensed under the Affero General Public License version 3 or
# later.
#
# See the COPYING-README file
#
###
angular.module('News').factory '_ItemController', ['Controller', (Controller) ->
class ItemController extends Controller
constructor: (@$scope, @itemModel, @activeFeed, @persistence, @feedModel,
@starredCount, @garbageRegistry, @showAll, @loading
@$rootScope, @feedType) ->
@batchSize = 4
@loaderQueue = 0
@$scope.getItems = (type, id) =>
return @itemModel.getItemsByTypeAndId(type, id)
@$scope.items = @itemModel.getItems()
@$scope.loading = @loading
@$scope.scroll = =>
@$scope.activeFeed = @activeFeed
@$scope.$on 'read', (scope, params) =>
@$scope.markRead(params.id, params.feed)
@$scope.loadFeed = (feedId) =>
params =
id: feedId
type: @feedType.Feed
@$rootScope.$broadcast 'loadFeed', params
@$scope.markRead = (itemId, feedId) =>
item = @itemModel.getItemById(itemId)
feed = @feedModel.getItemById(feedId)
if not item.keptUnread && !item.isRead
item.isRead = true
feed.unreadCount -= 1
# this item will be completely deleted if showAll is false
if not @showAll.showAll
@garbageRegistry.register(item)
@persistence.markRead(itemId, true)
@$scope.keepUnread = (itemId, feedId) =>
item = @itemModel.getItemById(itemId)
feed = @feedModel.getItemById(feedId)
item.keptUnread = !item.keptUnread
if item.isRead
item.isRead = false
feed.unreadCount += 1
@persistence.markRead(itemId, false)
@$scope.isKeptUnread = (itemId) =>
return @itemModel.getItemById(itemId).keptUnread
@$scope.toggleImportant = (itemId) =>
item = @itemModel.getItemById(itemId)
# cache
@itemModel.setImportant(itemId, !item.isImportant)
if item.isImportant
@starredCount.count += 1
else
@starredCount.count -= 1
@persistence.setImportant(itemId, item.isImportant)
return ItemController
]

Просмотреть файл

@ -1,60 +0,0 @@
###
# ownCloud news app
#
# @author Alessandro Cosentino
# @author Bernhard Posselt
# Copyright (c) 2012 - Alessandro Cosentino <cosenal@gmail.com>
# Copyright (c) 2012 - Bernhard Posselt <nukeawhale@gmail.com>
#
# This file is licensed under the Affero General Public License version 3 or
# later.
#
# See the COPYING-README file
#
###
angular.module('News').factory '_SettingsController', ['Controller',
(Controller) ->
class SettingsController extends Controller
constructor: (@$scope, @$rootScope, @persistence, @opmlParser, @feedModel) ->
@$scope.feeds = @feedModel.getItems()
@$scope.$on 'readFile', (scope, fileContent) =>
structure = @opmlParser.parseXML(fileContent)
@parseOPMLStructure(structure)
@$scope.$on 'hidesettings', =>
@$scope.showSettings = false
@$scope.export = =>
@export()
export: ->
# FIXME: this should only work when the routes are loaded
# and be put into a directive
url = OC.Router.generate('news_export_opml')
window.open url, '_blank'
# recursively create folders
parseOPMLStructure: (structure, folderId=0) ->
for item in structure.getItems()
if item.isFolder()
onSuccess = (data) =>
console.log data
folderId = data.folders[0].id
@parseOPMLStructure(item, folderId)
@persistence.createFolder(item.getName(), onSuccess)
else
# FIXME: handle errors
onSuccess = ->
onError = ->
@persistence.createFeed(item.getUrl(), folderId, onSuccess, onError)
return SettingsController
]

Просмотреть файл

@ -1,33 +0,0 @@
###
# ownCloud news app
#
# @author Alessandro Cosentino
# @author Bernhard Posselt
# Copyright (c) 2012 - Alessandro Cosentino <cosenal@gmail.com>
# Copyright (c) 2012 - Bernhard Posselt <nukeawhale@gmail.com>
#
# This file is licensed under the Affero General Public License version 3 or
# later.
#
# See the COPYING-README file
#
###
###
Turns a normal select into a folder select with the ability to create new folders
###
angular.module('News').directive 'addFolderSelect', ['$rootScope', ->
return (scope, elm, attr) ->
options =
singleSelect: true
selectedFirst: true
createText: $(elm).data('create')
createdCallback: (selected, value) ->
console.log selected
console.log value
$(elm).multiSelect(options)
]

Просмотреть файл

@ -1,55 +0,0 @@
###
# ownCloud news app
#
# @author Alessandro Cosentino
# @author Bernhard Posselt
# Copyright (c) 2012 - Alessandro Cosentino <cosenal@gmail.com>
# Copyright (c) 2012 - Bernhard Posselt <nukeawhale@gmail.com>
#
# This file is licensed under the Affero General Public License version 3 or
# later.
#
# See the COPYING-README file
#
###
###
Used to slide up an area and can be customized by passing an expression.
If selector is defined, a different area is slid up on click
If hideOnFocusLost is defined, the slid up area will hide when the focus is lost
###
angular.module('News').directive 'clickSlideToggle',
['$rootScope', ($rootScope) ->
return (scope, elm, attr) ->
options = scope.$eval(attr.clickSlideToggle)
if angular.isDefined(options.selector)
slideArea = $(options.selector)
else
slideArea = elm
elm.click ->
if slideArea.is(':visible') and not slideArea.is(':animated')
slideArea.slideUp()
else
slideArea.slideDown()
if angular.isDefined(options.hideOnFocusLost) and options.hideOnFocusLost
$(document.body).click ->
$rootScope.$broadcast 'lostFocus'
$rootScope.$on 'lostFocus', (scope, params) ->
if params != slideArea
if slideArea.is(':visible') and not slideArea.is(':animated')
slideArea.slideUp()
slideArea.click (e) ->
$rootScope.$broadcast 'lostFocus', slideArea
e.stopPropagation()
elm.click (e) ->
$rootScope.$broadcast 'lostFocus', slideArea
e.stopPropagation()
]

Просмотреть файл

@ -1,28 +0,0 @@
###
# ownCloud news app
#
# @author Alessandro Cosentino
# @author Bernhard Posselt
# Copyright (c) 2012 - Alessandro Cosentino <cosenal@gmail.com>
# Copyright (c) 2012 - Bernhard Posselt <nukeawhale@gmail.com>
#
# This file is licensed under the Affero General Public License version 3 or
# later.
#
# See the COPYING-README file
#
###
angular.module('News').directive 'draggable', ->
return (scope, elm, attr) ->
details =
revert: true
stack: '> li'
zIndex: 1000
axis: 'y'
helper: 'clone'
$(elm).draggable(details)

Просмотреть файл

@ -1,37 +0,0 @@
###
# ownCloud news app
#
# @author Alessandro Cosentino
# @author Bernhard Posselt
# Copyright (c) 2012 - Alessandro Cosentino <cosenal@gmail.com>
# Copyright (c) 2012 - Bernhard Posselt <nukeawhale@gmail.com>
#
# This file is licensed under the Affero General Public License version 3 or
# later.
#
# See the COPYING-README file
#
###
angular.module('News').directive 'droppable', ['$rootScope', ($rootScope) ->
return (scope, elm, attr) ->
$elem = $(elm)
details =
accept: '.feed'
hoverClass: 'drag-and-drop'
greedy: true
drop: (event, ui) ->
# in case jquery ui did something weird
$('.drag-and-drop').removeClass('drag-and-drop')
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)
]

Просмотреть файл

@ -1,70 +0,0 @@
###
# ownCloud news app
#
# @author Alessandro Cosentino
# @author Bernhard Posselt
# Copyright (c) 2012 - Alessandro Cosentino <cosenal@gmail.com>
# Copyright (c) 2012 - Bernhard Posselt <nukeawhale@gmail.com>
#
# This file is licensed under the Affero General Public License version 3 or
# later.
#
# See the COPYING-README file
#
###
angular.module('News').directive 'feedNavigation', ->
return (scope, elm, attr) ->
jumpTo = ($scrollArea, $item) ->
position = $item.offset().top - $scrollArea.offset().top + $scrollArea.scrollTop()
$scrollArea.scrollTop(position)
jumpToPreviousItem = (scrollArea) ->
$scrollArea = $(scrollArea)
$items = $scrollArea.find('.feed_item')
notJumped = true
for item in $items
$item = $(item)
if $item.position().top >= 0
$previous = $item.prev()
# if there are no items before the current one
if $previous.length > 0
jumpTo($scrollArea, $previous)
notJumped = false
break
# in case we didnt jump
if $items.length > 0 and notJumped
jumpTo($scrollArea, $items.last())
jumpToNextItem = (scrollArea) ->
$scrollArea = $(scrollArea)
$items = $scrollArea.find('.feed_item')
for item in $items
$item = $(item)
if $item.position().top > 1
jumpTo($scrollArea, $item)
break
$(document).keydown (e) ->
# only activate if no input elements is focused
focused = $(':focus')
if not (focused.is('input') or focused.is('select') or
focused.is('textarea') or focused.is('checkbox') or focused.is('button'))
scrollArea = elm
# j or right
if e.keyCode == 74 or e.keyCode == 39
jumpToNextItem(scrollArea)
# k or left
else if e.keyCode == 75 or e.keyCode == 37
jumpToPreviousItem(scrollArea)

Просмотреть файл

@ -1,29 +0,0 @@
###
# ownCloud news app
#
# @author Alessandro Cosentino
# @author Bernhard Posselt
# Copyright (c) 2012 - Alessandro Cosentino <cosenal@gmail.com>
# Copyright (c) 2012 - Bernhard Posselt <nukeawhale@gmail.com>
#
# This file is licensed under the Affero General Public License version 3 or
# later.
#
# See the COPYING-README file
#
###
###
Used to forward clicks to another element via jquery selector
The expression which can be passed looks like this {selector:'#opml-upload'}
###
angular.module('News').directive 'forwardClick', ->
return (scope, elm, attr) ->
options = scope.$eval(attr.forwardClick)
if angular.isDefined(options.selector)
elm.click ->
$(options.selector).trigger('click')

Просмотреть файл

@ -1,24 +0,0 @@
###
# ownCloud news app
#
# @author Alessandro Cosentino
# @author Bernhard Posselt
# Copyright (c) 2012 - Alessandro Cosentino <cosenal@gmail.com>
# Copyright (c) 2012 - Bernhard Posselt <nukeawhale@gmail.com>
#
# This file is licensed under the Affero General Public License version 3 or
# later.
#
# See the COPYING-README file
#
###
angular.module('News').directive 'onEnter', ->
return (scope, elm, attr) ->
elm.bind 'keyup', (e) ->
if e.keyCode == 13
e.preventDefault()
scope.$apply attr.onEnter

Просмотреть файл

@ -1,37 +0,0 @@
###
# ownCloud news app
#
# @author Alessandro Cosentino
# @author Bernhard Posselt
# Copyright (c) 2012 - Alessandro Cosentino <cosenal@gmail.com>
# Copyright (c) 2012 - Bernhard Posselt <nukeawhale@gmail.com>
#
# This file is licensed under the Affero General Public License version 3 or
# later.
#
# See the COPYING-README file
#
###
###
Thise directive can be bound on an input element with type file and name files []
When a file is input, the content will be broadcasted as a readFile event
###
angular.module('News').directive 'readFile', ['$rootScope', ($rootScope) ->
return (scope, elm, attr) ->
$(elm).change ->
if window.File and window.FileReader and window.FileList
file = elm[0].files[0]
reader = new FileReader()
reader.onload = (e) ->
content = e.target.result
$rootScope.$broadcast 'readFile', content
reader.readAsText(file)
else
alert 'Your browser does not support the FileReader API!'
]

Просмотреть файл

@ -1,56 +0,0 @@
###
# ownCloud news app
#
# @author Alessandro Cosentino
# @author Bernhard Posselt
# Copyright (c) 2012 - Alessandro Cosentino <cosenal@gmail.com>
# Copyright (c) 2012 - Bernhard Posselt <nukeawhale@gmail.com>
#
# This file is licensed under the Affero General Public License version 3 or
# later.
#
# See the COPYING-README file
#
###
scrolling = true
markingRead = true
angular.module('News').directive 'whenScrolled',
['$rootScope', 'Config',
($rootScope, Config) ->
return (scope, elm, attr) ->
elm.bind 'scroll', ->
# prevent from doing to many scroll actions
# the first timeout prevents accidental and too early marking as read
if scrolling
scrolling = false
setTimeout ->
scrolling = true
, Config.ScrollTimeout
if markingRead
markingRead = false
setTimeout ->
markingRead = true
# only broadcast elements that are not already read
# and that are beyond the top border
$elems = $(elm).find('.feed_item:not(.read)')
for feedItem in $elems
offset = $(feedItem).position().top
if offset <= -50
id = parseInt($(feedItem).data('id'), 10)
feed = parseInt($(feedItem).data('feed'), 10)
$rootScope.$broadcast('read', {id: id, feed: feed})
else
break
, Config.MarkReadTimeout
scope.$apply attr.whenScrolled
]

Просмотреть файл

@ -1,22 +0,0 @@
###
# ownCloud news app
#
# @author Alessandro Cosentino
# @author Bernhard Posselt
# Copyright (c) 2012 - Alessandro Cosentino <cosenal@gmail.com>
# Copyright (c) 2012 - Bernhard Posselt <nukeawhale@gmail.com>
#
# This file is licensed under the Affero General Public License version 3 or
# later.
#
# See the COPYING-README file
#
###
angular.module('News').filter 'feedInFolder', ->
return (feeds, folderId) ->
result = []
for feed in feeds
if feed.folderId == folderId
result.push(feed)
return result

Просмотреть файл

@ -1,27 +0,0 @@
###
# ownCloud
#
# @author Bernhard Posselt
# Copyright (c) 2012 - Bernhard Posselt <nukeawhale@gmail.com>
#
# This file is licensed under the Affero General Public License version 3 or
# later.
#
# See the COPYING-README file
#
###
###
Used to forward clicks to another element via jquery selector
The expression which can be passed looks like this {selector:'#opml-upload'}
###
angular.module('OC').directive 'forwardClick', ->
return (scope, elm, attr) ->
options = scope.$eval(attr.forwardClick)
if angular.isDefined(options.selector)
elm.click ->
$(options.selector).trigger('click')

Просмотреть файл

@ -1,44 +0,0 @@
###
# ownCloud
#
# @author Bernhard Posselt
# Copyright (c) 2012 - Bernhard Posselt <nukeawhale@gmail.com>
#
# This file is licensed under the Affero General Public License version 3 or
# later.
#
# See the COPYING-README file
#
###
###
# Various config stuff for owncloud
###
angular.module('OC', []).config ['$httpProvider', ($httpProvider) ->
# Always send the CSRF token by default
$httpProvider.defaults.get['requesttoken'] = oc_requesttoken
$httpProvider.defaults.post['requesttoken'] = oc_requesttoken
# needed because crap PHP does not understand JSON
$httpProvider.defaults.post['Content-Type'] =
'application/x-www-form-urlencoded'
$httpProvider.defaults.get['Content-Type'] =
'application/x-www-form-urlencoded'
$httpProvider.defaults.transformRequest = (data) ->
if angular.isDefined(data)
return data
else
return $.param(data)
]
angular.module('OC').run ['$rootScope', 'Router', ($rootScope, Router) ->
init = ->
$rootScope.$broadcast('routesLoaded')
# this registers a callback that is executed once the routes have
# finished loading. Before this you cant really do request
Router.registerLoadedCallback(init)
]

Просмотреть файл

@ -1,18 +0,0 @@
###
# ownCloud
#
# @author Bernhard Posselt
# Copyright (c) 2012 - Bernhard Posselt <nukeawhale@gmail.com>
#
# This file is licensed under the Affero General Public License version 3 or
# later.
#
# See the COPYING-README file
#
###
###
# Inject notification into angular to make testing easier
###
angular.module('OC').factory 'Notification', ->
return OC.Notification

Просмотреть файл

@ -1,56 +0,0 @@
###
# ownCloud
#
# @author Bernhard Posselt
# Copyright (c) 2012 - Bernhard Posselt <nukeawhale@gmail.com>
#
# This file is licensed under the Affero General Public License version 3 or
# later.
#
# See the COPYING-README file
#
###
###
# Used for properly distributing received model data from the server
###
angular.module('OC').factory '_Publisher', ->
class Publisher
constructor: ->
@subscriptions = {}
# Use this to subscribe to a certain hashkey in the returned json data
# dictionary.
# If you send JSON from the server, you'll receive something like this
#
# {
# data: {
# modelName: {
# create: [{id: 1, name: 'john'}, {id: 2, name: 'ron'}],
# update: [],
# delete: []
# }
# }
# }
#
# To get the array ['one', 'two'] passed to your model, just subscribe
# to the key:
# Publisher.subscribeModelTo('modelName', myModelInstance)
#
subscribeModelTo: (model, name) ->
@subscriptions[name] or= []
@subscriptions[name].push(model)
# This will publish data from the server to all registered subscribers
# The parameter 'name' is the name under which subscribers have registered
publishDataTo: (data, name) ->
for subscriber in @subscriptions[name] || []
subscriber.handle(data)
return Publisher

Просмотреть файл

@ -1,76 +0,0 @@
###
# ownCloud
#
# @author Bernhard Posselt
# Copyright (c) 2012 - Bernhard Posselt <nukeawhale@gmail.com>
#
# This file is licensed under the Affero General Public License version 3 or
# later.
#
# See the COPYING-README file
#
###
angular.module('OC').factory '_Request', ->
class Request
constructor: (@_$http, @_$rootScope, @_publisher, @_token, @_router) ->
@_initialized = false
@_shelvedRequests = []
@_$rootScope.$on 'routesLoaded', =>
@_executeShelvedRequests()
@_initialized = true
@_shelvedRequests = []
request: (route, routeParams={}, data={}, onSuccess=null, onFailure=null, config={}) ->
# if routes are not ready yet, save the request
if not @_initialized
@_shelveRequest(route, routeParams, data, method, config)
return
url = @_router.generate(route, routeParams)
defaultConfig =
method: 'GET'
url: url
data: data
# overwrite default values from passed in config
for key, value of config
defaultConfig[key] = value
@_$http(config)
.success (data, status, headers, config) =>
if onSuccess
onSuccess(data, status, headers, config)
# publish data to models
for name, value of data.data
@publisher.publishDataTo(name, value)
.error (data, status, headers, config) ->
if onFailure
onFailure(data, status, headers, config)
_shelveRequest: (route, routeParams, data, method, config) ->
request =
route: route
routeParams: routeParams
data: data
config: config
method: method
@_shelvedRequests.push(request)
_executeShelvedRequests: ->
for req in @_shelvedRequests
@post(req.route, req.routeParams, req.data, req.method, req.config)
return Request

Просмотреть файл

@ -1,18 +0,0 @@
###
# ownCloud
#
# @author Bernhard Posselt
# Copyright (c) 2012 - Bernhard Posselt <nukeawhale@gmail.com>
#
# This file is licensed under the Affero General Public License version 3 or
# later.
#
# See the COPYING-README file
#
###
###
# Inject router into angular to make testing easier
###
angular.module('OC').factory 'Router', ->
return OC.Router

Просмотреть файл

@ -1,28 +0,0 @@
{
"name": "owncloud-news-app",
"description": "ownCloud RSS reader app",
"version": "0.0.1",
"author": "ownCloud <owncloud@kde.org>",
"private": true,
"contributors": [
{
"name": "Alessandro Cosentino",
"email": "cosenal@gmail.com"
},
{
"name": "Bernhard Posselt",
"email": "nukeawhale@gmail.com"
}
],
"devDependencies": {
"grunt": "~0.4.0rc8",
"grunt-cli": "~0.1.6",
"coffee-script": "~1.4.0",
"grunt-contrib-coffee": "~0.4.0rc7",
"grunt-contrib-concat": "~0.1.2rc6",
"grunt-contrib-watch": "~0.2.0rc7",
"grunt-coffeelint": "0.0.4",
"gruntacular": "~0.1.1"
},
"engine": "node >= 0.8"
}

Просмотреть файл

@ -1,28 +0,0 @@
###
# ownCloud news app
#
# @author Alessandro Cosentino
# @author Bernhard Posselt
# Copyright (c) 2012 - Alessandro Cosentino <cosenal@gmail.com>
# Copyright (c) 2012 - Bernhard Posselt <nukeawhale@gmail.com>
#
# This file is licensed under the Affero General Public License version 3 or
# later.
#
# See the COPYING-README file
#
###
angular.module('News').factory '_ActiveFeed', ->
class ActiveFeed
constructor: ->
@id = 0
@type = 3
handle: (data) ->
@id = data.id
@type = data.type
return ActiveFeed

Просмотреть файл

@ -1,164 +0,0 @@
###
# ownCloud news app
#
# @author Alessandro Cosentino
# @author Bernhard Posselt
# Copyright (c) 2012 - Alessandro Cosentino <cosenal@gmail.com>
# Copyright (c) 2012 - Bernhard Posselt <nukeawhale@gmail.com>
#
# This file is licensed under the Affero General Public License version 3 or
# later.
#
# See the COPYING-README file
#
###
angular.module('News').factory '_Cache', ->
class Cache
constructor: (@feedType, @feedModel, @folderModel) ->
@clear()
clear: ->
@feedCache = []
@folderCache = {}
@folderCacheLastModified = 0
@importantCache = []
@highestId = 0
@lowestId = 0
@highestTimestamp = 0
@lowestTimestamp = 0
@highestIds = {}
@lowestIds = {}
@highestTimestamps = {}
@lowestTimestamps = {}
add: (item) ->
# cache for feed access
if not @feedCache[item.feedId]
@feedCache[item.feedId] = []
@feedCache[item.feedId].push(item)
# cache for non feeds
if @highestTimestamp < item.date
@highestTimestamp = item.date
if @lowestTimestamp > item.date
@lowestTimestamp = item.date
if @highestId < item.id
@highestId = item.id
if @lowestId > item.id
@lowestId = item.id
# cache for important
if item.isImportant
@importantCache.push(item)
# cache lowest and highest ids and timestamps for only fetching new
# items
if @highestTimestamps[item.feedId] == undefined or item.id > @highestTimestamps[item.feedId]
@highestTimestamps[item.feedId] = item.date
if @lowestTimestamps[item.feedId] == undefined or item.id > @lowestTimestamps[item.feedId]
@lowestTimestamps[item.feedId] = item.date
if @highestIds[item.feedId] == undefined or item.id > @highestIds[item.feedId]
@highestIds[item.feedId] = item.id
if @lowestIds[item.feedId] == undefined or item.id > @lowestIds[item.feedId]
@lowestIds[item.feedId] = item.id
getItemsOfFeed: (feedId) ->
return @feedCache[feedId]
getFeedIdsOfFolder: (folderId) ->
@buildFolderCache(folderId)
return @folderCache[folderId]
getImportantItems: ->
return @importantCache
buildFolderCache: (id) ->
# invalidate the foldercache if the last modified date is
# not the currently used one
if @folderCacheLastModified != @feedModel.getLastModified()
@folderCache = {}
@folderCacheLastModified = @feedModel.getLastModified()
# if the folderarray does not yet exist, build it
# otherwise use the last generated one
if @folderCache[id] == undefined
@folderCache[id] = []
for feed in @feedModel.getItems()
if feed.folderId == id
@folderCache[id].push(feed.id)
getFeedsOfFolderId: (id) ->
@buildFolderCache(id)
return @folderCache[id]
removeItemInArray: (id, array) ->
removeItemIndex = null
counter = 0
for element in array
if element.id == id
removeItemIndex = counter
break
counter += 1
if removeItemIndex != null
array.splice(removeItemIndex, 1)
remove: (item) ->
@removeItemInArray(item.id, @feedCache[item.feedId])
@removeItemInArray(item.id, @importantCache)
setImportant: (item, isImportant) ->
if isImportant
@importantCache.push(item)
else
@removeItemInArray(item.id, @importantCache)
getHighestId: (type, id) ->
if @isFeed(type)
return @highestIds[id] || 0
else
return @highestId
getHighestTimestamp: (type, id) ->
if @isFeed(type)
return @highestTimestamps[id] || 0
else
return @highestTimestamp
getLowestId: (type, id) ->
if @isFeed(type)
return @lowestIds[id] || 0
else
return @lowestId
getLowestTimestamp: (type, id) ->
if @isFeed(type)
return @lowestTimestamps[id] || 0
else
return @lowestTimestamp
isFeed: (type) ->
return type == @feedType.Feed
return Cache

Просмотреть файл

@ -1,35 +0,0 @@
###
# ownCloud news app
#
# @author Alessandro Cosentino
# @author Bernhard Posselt
# Copyright (c) 2012 - Alessandro Cosentino <cosenal@gmail.com>
# Copyright (c) 2012 - Bernhard Posselt <nukeawhale@gmail.com>
#
# This file is licensed under the Affero General Public License version 3 or
# later.
#
# See the COPYING-README file
#
###
angular.module('News').factory '_FeedModel', ['Model', (Model) ->
class FeedModel extends Model
constructor: () ->
super()
add: (item) ->
super(@bindAdditional(item))
bindAdditional: (item) ->
if item.icon == "url()"
item.icon = 'url(' + OC.imagePath('news', 'rss.svg') + ')'
return item
return FeedModel
]

Просмотреть файл

@ -1,22 +0,0 @@
###
# ownCloud news app
#
# @author Alessandro Cosentino
# @author Bernhard Posselt
# Copyright (c) 2012 - Alessandro Cosentino <cosenal@gmail.com>
# Copyright (c) 2012 - Bernhard Posselt <nukeawhale@gmail.com>
#
# This file is licensed under the Affero General Public License version 3 or
# later.
#
# See the COPYING-README file
#
###
angular.module('News').factory 'FeedType', ->
feedType =
Feed: 0
Folder: 1
Starred: 2
Subscriptions: 3
Shared: 4

Просмотреть файл

@ -1,25 +0,0 @@
###
# ownCloud news app
#
# @author Alessandro Cosentino
# @author Bernhard Posselt
# Copyright (c) 2012 - Alessandro Cosentino <cosenal@gmail.com>
# Copyright (c) 2012 - Bernhard Posselt <nukeawhale@gmail.com>
#
# This file is licensed under the Affero General Public License version 3 or
# later.
#
# See the COPYING-README file
#
###
angular.module('News').factory '_FolderModel', ['Model', (Model, $rootScope) ->
class FolderModel extends Model
constructor: ->
super()
return FolderModel
]

Просмотреть файл

@ -1,42 +0,0 @@
###
# ownCloud news app
#
# @author Alessandro Cosentino
# @author Bernhard Posselt
# Copyright (c) 2012 - Alessandro Cosentino <cosenal@gmail.com>
# Copyright (c) 2012 - Bernhard Posselt <nukeawhale@gmail.com>
#
# This file is licensed under the Affero General Public License version 3 or
# later.
#
# See the COPYING-README file
#
###
angular.module('News').factory '_GarbageRegistry', ->
class GarbageRegistry
constructor: (@itemModel) ->
@registeredItemIds = {}
register: (item) ->
itemId = item.id
@registeredItemIds[itemId] = item
unregister: (item) ->
itemId = item.id
delete @registeredItemIds[itemId]
clear: () ->
# delete read items for performance reasons when showAll == false
for id, item of @registeredItemIds
if not item.keptUnread
@itemModel.removeById(parseInt(id, 10))
item.keptUnread = false
@registeredItemIds = {}
return GarbageRegistry

Просмотреть файл

@ -1,101 +0,0 @@
###
# ownCloud news app
#
# @author Alessandro Cosentino
# @author Bernhard Posselt
# Copyright (c) 2012 - Alessandro Cosentino <cosenal@gmail.com>
# Copyright (c) 2012 - Bernhard Posselt <nukeawhale@gmail.com>
#
# This file is licensed under the Affero General Public License version 3 or
# later.
#
# See the COPYING-README file
#
###
angular.module('News').factory '_ItemModel', ['Model', (Model) ->
class ItemModel extends Model
constructor: (@cache, @feedType) ->
super()
clearCache: () ->
@cache.clear()
super()
add: (item) ->
item = @bindAdditional(item)
if super(item)
@cache.add(@getItemById(item.id))
bindAdditional: (item) ->
item.getRelativeDate = ->
return moment.unix(this.date).fromNow();
item.getAuthorLine = ->
if this.author != null and this.author.trim() != ""
return "by " + this.author
else
return ""
return item
removeById: (itemId) ->
item = @getItemById(itemId)
if item != undefined
@cache.remove(item)
super(itemId)
getHighestId: (type, id) ->
@cache.getHighestId(type, id)
getHighestTimestamp: (type, id) ->
@cache.getHighestTimestamp(type, id)
getLowestId: (type, id) ->
@cache.getLowestId(type, id)
getLowestTimestamp: (type, id) ->
@cache.getLowestTimestamp(type, id)
getFeedsOfFolderId: (id) ->
@cache.getFeedsOfFolderId(id)
getItemsByTypeAndId: (type, id) ->
switch type
when @feedType.Feed
items = @cache.getItemsOfFeed(id) || []
return items
when @feedType.Subscriptions
return @getItems()
when @feedType.Folder
items = []
for feedId in @cache.getFeedIdsOfFolder(id)
items = items.concat(@cache.getItemsOfFeed(feedId) || [])
return items
when @feedType.Starred
return @cache.getImportantItems()
setImportant: (itemId, isImportant) ->
item = @getItemById(itemId)
@cache.setImportant(item, isImportant)
item.isImportant = isImportant
return ItemModel
]

Просмотреть файл

@ -1,21 +0,0 @@
###
# ownCloud news app
#
# @author Alessandro Cosentino
# @author Bernhard Posselt
# Copyright (c) 2012 - Alessandro Cosentino <cosenal@gmail.com>
# Copyright (c) 2012 - Bernhard Posselt <nukeawhale@gmail.com>
#
# This file is licensed under the Affero General Public License version 3 or
# later.
#
# See the COPYING-README file
#
###
angular.module('News').factory '_Loading', ->
class Loading
constructor: ->
@loading = 0

Просмотреть файл

@ -1,84 +0,0 @@
###
# ownCloud news app
#
# @author Alessandro Cosentino
# @author Bernhard Posselt
# Copyright (c) 2012 - Alessandro Cosentino <cosenal@gmail.com>
# Copyright (c) 2012 - Bernhard Posselt <nukeawhale@gmail.com>
#
# This file is licensed under the Affero General Public License version 3 or
# later.
#
# See the COPYING-README file
#
###
angular.module('News').factory 'Model', ->
class Model
constructor: () ->
@clearCache()
handle: (data) ->
for item in data
@add(item)
clearCache: () ->
@items = []
@itemIds = {}
@markAccessed()
markAccessed: () ->
@lastAccessed = new Date().getTime()
getLastModified: () ->
return @lastAccessed
add: (item) ->
if @itemIds[item.id] == undefined
@items.push(item)
@itemIds[item.id] = item
@markAccessed()
return true
else
@update(item)
return false
update: (item) ->
updatedItem = @itemIds[item.id]
for key, value of item
if key != 'id'
updatedItem[key] = value
@markAccessed()
removeById: (id) ->
removeItemIndex = null
counter = 0
for item in @items
if item.id == id
removeItemIndex = counter
break
counter += 1
if removeItemIndex != null
@items.splice(removeItemIndex, 1)
delete @itemIds[id]
@markAccessed()
getItemById: (id) ->
return @itemIds[id]
getItems: () ->
return @items
return Model

Просмотреть файл

@ -1,71 +0,0 @@
###
# ownCloud news app
#
# @author Alessandro Cosentino
# @author Bernhard Posselt
# Copyright (c) 2012 - Alessandro Cosentino <cosenal@gmail.com>
# Copyright (c) 2012 - Bernhard Posselt <nukeawhale@gmail.com>
#
# This file is licensed under the Affero General Public License version 3 or
# later.
#
# See the COPYING-README file
#
###
angular.module('News').factory '_OPMLParser', ->
class Feed
constructor: (@name, @url) ->
getName: ->
return @name
getUrl: ->
return @url
isFolder: ->
return false
class Folder
constructor: (@name) ->
@items = []
add: (feed) ->
@items.push(feed)
getItems: ->
return @items
getName: ->
return @name
isFolder: ->
return true
class OPMLParser
parseXML: (xml) ->
$xml = $($.parseXML(xml))
$root = $xml.find('body')
structure = new Folder('root')
@_recursivelyParse($root, structure)
return structure
_recursivelyParse: ($xml, structure) ->
for outline in $xml.children('outline')
$outline = $(outline)
if $outline.attr('type') != undefined
feed = new Feed($outline.attr('text'), $outline.attr('xmlUrl'))
structure.add(feed)
else
folder = new Folder($outline.attr('text'))
structure.add(folder)
@_recursivelyParse($outline, folder)
return OPMLParser

Просмотреть файл

@ -1,77 +0,0 @@
###
# ownCloud news app
#
# @author Alessandro Cosentino
# @author Bernhard Posselt
# Copyright (c) 2012 - Alessandro Cosentino <cosenal@gmail.com>
# Copyright (c) 2012 - Bernhard Posselt <nukeawhale@gmail.com>
#
# This file is licensed under the Affero General Public License version 3 or
# later.
#
# See the COPYING-README file
#
###
angular.module('News').factory 'Persistence', ->
class Persistence
constructor: (@appName, @$http) ->
@appInitialized = false
@shelvedRequests = []
setInitialized: (isInitialized) ->
if isInitialized
@executePostRequests()
@appInitialized = isInitialized
executePostRequests: () ->
for request in @shelvedRequests
@post(request.route, request.data, request.callback)
console.log request
@shelvedRequests = []
isInitialized: ->
return @appInitialized
post: (route, data={}, callback, errorCallback, init=false, contentType='application/x-www-form-urlencoded') ->
if @isInitialized == false && init == false
request =
route: route
data: data
callback: callback
@shelvedRequests.push(request)
return
if not callback
callback = ->
if not errorCallback
errorCallback = ->
url = OC.Router.generate("news_ajax_" + route)
data = $.param(data)
# csrf token
headers =
requesttoken: oc_requesttoken
'Content-Type': 'application/x-www-form-urlencoded'
@$http.post(url, data, {headers: headers}).
success((data, status, headers, config) ->
if data.status == "error"
errorCallback(data.msg)
else
callback(data)
).
error (data, status, headers, config) ->
console.warn('Error occured: ')
console.warn(status)
console.warn(headers)
console.warn(config)

Просмотреть файл

@ -1,154 +0,0 @@
###
# ownCloud news app
#
# @author Alessandro Cosentino
# @author Bernhard Posselt
# Copyright (c) 2012 - Alessandro Cosentino <cosenal@gmail.com>
# Copyright (c) 2012 - Bernhard Posselt <nukeawhale@gmail.com>
#
# This file is licensed under the Affero General Public License version 3 or
# later.
#
# See the COPYING-README file
#
###
angular.module('News').factory '_PersistenceNews', ['Persistence', (Persistence) ->
class PersistenceNews extends Persistence
constructor: ($http, @$rootScope, @loading, @publisher) ->
super('news', $http)
updateModels: (data) ->
for type, value of data
@publisher.publish(type, value)
loadInitial: () ->
@loading.loading += 1
OC.Router.registerLoadedCallback =>
@post 'init', {}, (json) =>
@loading.loading -= 1
@updateModels(json.data)
@$rootScope.$broadcast('triggerHideRead')
@setInitialized(true)
, null, true
loadFeed: (type, id, latestFeedId, latestTimestamp, limit=20) ->
data =
type: type
id: id
latestFeedId: latestFeedId
latestTimestamp: latestTimestamp
limit: limit
@loading.loading += 1
@post 'loadfeed', data, (json) =>
@loading.loading -= 1
@updateModels(json.data)
createFeed: (feedUrl, folderId, onSuccess, onError) ->
data =
feedUrl: feedUrl
folderId: folderId
@post 'createfeed', data, (json) =>
onSuccess(json.data)
@updateModels(json.data)
, onError
deleteFeed: (feedId, onSuccess) ->
data =
feedId: feedId
@post 'deletefeed', data, onSuccess
moveFeedToFolder: (feedId, folderId) ->
data =
feedId: feedId
folderId: folderId
@post 'movefeedtofolder', data
createFolder: (folderName, onSuccess) ->
data =
folderName: folderName
@post 'createfolder', data, (json) =>
onSuccess(json.data)
@updateModels(json.data)
deleteFolder: (folderId) ->
data =
folderId: folderId
@post 'deletefolder', data
changeFolderName: (folderId, newFolderName) ->
data =
folderId: folderId
newFolderName: newFolderName
@post 'folderName', data
showAll: (isShowAll) ->
data =
showAll: isShowAll
@post 'setshowall', data
markRead: (itemId, isRead) ->
if isRead
status = 'read'
else
status = 'unread'
data =
itemId: itemId
status: status
@post 'setitemstatus', data
setImportant: (itemId, isImportant) ->
if isImportant
status = 'important'
else
status = 'unimportant'
data =
itemId: itemId
status: status
@post 'setitemstatus', data
collapseFolder: (folderId, value) ->
data =
folderId: folderId
opened: value
@post 'collapsefolder', data
updateFeed: (feedId) ->
data =
feedId: feedId
@post 'updatefeed', data, (json) =>
@updateModels(json.data)
setAllItemsRead: (feedId, mostRecentItemId) ->
data =
feedId: feedId
mostRecentItemId: mostRecentItemId
@post 'setallitemsread', data
return PersistenceNews
]

Просмотреть файл

@ -1,34 +0,0 @@
###
# ownCloud news app
#
# @author Alessandro Cosentino
# @author Bernhard Posselt
# Copyright (c) 2012 - Alessandro Cosentino <cosenal@gmail.com>
# Copyright (c) 2012 - Bernhard Posselt <nukeawhale@gmail.com>
#
# This file is licensed under the Affero General Public License version 3 or
# later.
#
# See the COPYING-README file
#
###
angular.module('News').factory '_Publisher', ->
class Publisher
constructor: () ->
@subscriptions = {}
subscribeTo: (type, object) ->
@subscriptions[type] or= []
@subscriptions[type].push(object)
publish: (type, message) ->
for subscriber in @subscriptions[type] || []
subscriber.handle(message)
return Publisher

Просмотреть файл

@ -1,94 +0,0 @@
###
# ownCloud news app
#
# @author Alessandro Cosentino
# @author Bernhard Posselt
# Copyright (c) 2012 - Alessandro Cosentino <cosenal@gmail.com>
# Copyright (c) 2012 - Bernhard Posselt <nukeawhale@gmail.com>
#
# This file is licensed under the Affero General Public License version 3 or
# later.
#
# See the COPYING-README file
#
###
angular.module('News').factory 'Loading',
['_Loading', (_Loading) ->
return new _Loading()
]
# Models
angular.module('News').factory 'ActiveFeed',
['_ActiveFeed', 'Publisher', (_ActiveFeed, Publisher) ->
model = new _ActiveFeed()
Publisher.subscribeTo('activeFeed', model)
return model
]
angular.module('News').factory 'ShowAll',
['_ShowAll', 'Publisher', (_ShowAll, Publisher) ->
model = new _ShowAll()
Publisher.subscribeTo('showAll', model)
return model
]
angular.module('News').factory 'StarredCount',
['_StarredCount', 'Publisher', (_StarredCount, Publisher) ->
model = new _StarredCount()
Publisher.subscribeTo('starredCount', model)
return model
]
angular.module('News').factory 'FeedModel',
['_FeedModel', 'Publisher',
(_FeedModel, Publisher) ->
model = new _FeedModel()
Publisher.subscribeTo('feeds', model)
return model
]
angular.module('News').factory 'FolderModel',
['_FolderModel', 'Publisher',
(_FolderModel, Publisher) ->
model = new _FolderModel()
Publisher.subscribeTo('folders', model)
return model
]
angular.module('News').factory 'ItemModel',
['_ItemModel', 'Publisher', 'Cache', 'FeedType',
(_ItemModel, Publisher, Cache, FeedType) ->
model = new _ItemModel(Cache, FeedType)
Publisher.subscribeTo('items', model)
return model
]
# Classes
angular.module('News').factory 'Cache',
['_Cache', 'FeedType', 'FeedModel', 'FolderModel',
(_Cache, FeedType, FeedModel, FolderModel) ->
return new _Cache(FeedType, FeedModel, FolderModel)
]
angular.module('News').factory 'PersistenceNews',
['_PersistenceNews', '$http', '$rootScope', 'Loading', 'Publisher',
(_PersistenceNews, $http, $rootScope, Loading, Publisher) ->
return new _PersistenceNews($http, $rootScope, Loading, Publisher)
]
angular.module('News').factory 'GarbageRegistry',
['_GarbageRegistry', 'ItemModel',
(_GarbageRegistry, ItemModel) ->
return new _GarbageRegistry(ItemModel)
]
angular.module('News').factory 'Publisher',
['_Publisher', (_Publisher) ->
return new _Publisher()
]
angular.module('News').factory 'OPMLParser',
['_OPMLParser', (_OPMLParser) ->
return new _OPMLParser()
]

Просмотреть файл

@ -1,27 +0,0 @@
###
# ownCloud news app
#
# @author Alessandro Cosentino
# @author Bernhard Posselt
# Copyright (c) 2012 - Alessandro Cosentino <cosenal@gmail.com>
# Copyright (c) 2012 - Bernhard Posselt <nukeawhale@gmail.com>
#
# This file is licensed under the Affero General Public License version 3 or
# later.
#
# See the COPYING-README file
#
###
angular.module('News').factory '_ShowAll', ->
class ShowAll
constructor: ->
@showAll = false
handle: (data) ->
@showAll = data
return ShowAll

Просмотреть файл

@ -1,28 +0,0 @@
###
# ownCloud news app
#
# @author Alessandro Cosentino
# @author Bernhard Posselt
# Copyright (c) 2012 - Alessandro Cosentino <cosenal@gmail.com>
# Copyright (c) 2012 - Bernhard Posselt <nukeawhale@gmail.com>
#
# This file is licensed under the Affero General Public License version 3 or
# later.
#
# See the COPYING-README file
#
###
angular.module('News').factory '_StarredCount', ->
class StarredCount
constructor: ->
@count = 0
handle: (data) ->
@count = data
return StarredCount

Двоичные данные
doc/.mapper spec.md.kate-swp

Двоичный файл не отображается.

Просмотреть файл

@ -1,81 +0,0 @@
# GUI Specification
This should be a document which specifies the GUI for testing purposes.
**This specification is not yet final and only reflects the current state**
## General
* When the programs is being launched the last viewed feed is being loaded by default
## Feed List
* You can click on the following entries:
* folders that contain feeds
* starred
* new articles
* When you click on a feed or folder it should:
* get the css class 'active'
* load the folder or feed into the right view
* When you hover over a feed it should:
* show a css hint that you hovered over it
* show the delete and mark all read button
* When you hover over a folder it should:
* show a css hint that you hovered over it
* show the edit, delete, mark all read button
* When you hover over a folder with feeds it should:
* show the collapse/open button (open button if opened, collapse button if collapsed
* When an entry has only read items it should have the all_read class
## Controls
* When you click on the plus button it should show a Menu which shows Feed and Folder
* When you click on the Settings symbol it should show the settings popup
* When you click on the eye symbol it should toggle the SHOW_ALL and SHOW_UNREAD mode
## Modes
### SHOW_ALL
* When you activate it it should
* Tell the server that its activated
* Empty the cache and reload the current items
* Show all feeds and folders in the feedlist
* Show all items in the itemslist
* Change the title of the eye button to "Show everything"
* Show empty folders
* When you click on a feed load read and unread items and show items with the read class
### SHOW_UNREAD
* When you activate it it should
* Tell the server that its activated
* Empty the cache and reload the current items
* Hide all feeds with all_read class in the feedlist. If all feeds of a folder are all_read, hide the folder.
* Hide empty folders
* Hide all items with read class in the itemslist
* Change the title of the eye button to "Show only unread"
* When the feed is selected (active class) and has the all_read class dont hide it and neither hide its parent folder but do so if it is deselected
* When you click on a feed only unread items and hide items with the read class
## Items
* Hover over a item should show the bottom util bar (keep unread)
* Click on the starred item should make it starred (add the class important) and tell the server that its starred and increase the unread count for starred items by 1
* Click on the header link or
Click on the text body or
Scrolling a feed beyond the top edge
* should mark it as read (add css read class) and tell the server that its marked read and decrease the unread count of the item and its top folder and unread articles by 1
* click on keep unread text or keep unread checkbox should
* **When not marked yet**:
* tell the server to make it unread
* prevent it from being marked read
* **When marked yet**:
* dont prevent it from being marked read

Просмотреть файл

@ -1,31 +0,0 @@
request: get just starred items of a user
SELECT * FROM items
WHERE user_id = ? AND status = ?
(AND id < ? LIMIT ?)
(AND items.lastmodified >= ?)
request: get all items of a user (unread and read)
SELECT * FROM items
WHERE user_id = ? AND status = ?
(AND id < ? LIMIT ?)
(AND items.lastmodified >= ?)
request: get all items of a folder of a user (unread and read)
SELECT * FROM items
JOIN feeds
ON feed.id = feed_id
WHERE user_id = ? AND status = ? AND feed.folder_id = ?
(AND id < ? LIMIT ?)
(AND items.lastmodified >= ?)
request: get all items of a feed of a user (unread and read)
SELECT * FROM items
WHERE user_id = ? AND status = ? AND feed_id = ?
(AND id < ? LIMIT ?)
(AND items.lastmodified >= ?)
all requests: can be specified using an (offset (id), limit) or (updatedSince (timestamp))