FeedBunch-app/app/assets/javascripts/ng-services/ng-EntrySvc.js.coffee.erb
########################################################
# AngularJS service to manage entries
########################################################
angular.module('feedbunch').service 'entrySvc',
['$rootScope', '$window', 'openEntrySvc', 'timerFlagSvc', 'changeUnreadCountSvc',
'currentFolderSvc', 'currentFeedSvc', 'findSvc', 'loadEntriesSvc', 'feedsFoldersTimerSvc', 'loadFeedsSvc',
'lazyLoadingSvc', 'tourSvc', 'animationsSvc', 'menuCollapseSvc', 'csrfTokenSvc',
($rootScope, $window, openEntrySvc, timerFlagSvc, changeUnreadCountSvc,
currentFolderSvc, currentFeedSvc, findSvc, loadEntriesSvc, feedsFoldersTimerSvc, loadFeedsSvc,
lazyLoadingSvc, tourSvc, animationsSvc, menuCollapseSvc, csrfTokenSvc)->
# Constants for the different operations the web worker can perform
CHANGE_SINGLE_ENTRY = 'change_single_entry'
CHANGE_MULTIPLE_ENTRIES = 'change_multiple_entries'
# CSRF token for POST
token = csrfTokenSvc.get_token()
# Web worker to change the state of entries in a different thread
worker = new Worker '<%= asset_path 'workers/change_entry_state_worker' %>'
worker.onmessage = (e) ->
if e.data.status == 200
feedsFoldersTimerSvc.reset_refresh_timer()
if e.data.operation == CHANGE_SINGLE_ENTRY
entry_state_changed e.data.params.entry.id
else if e.data.operation == CHANGE_MULTIPLE_ENTRIES
entries_states_changed()
else if e.data.status == 401 || e.data.status == 422
$window.location.href = '/login'
else
timerFlagSvc.start 'error_changing_entry_state'
$rootScope.$digest()
#--------------------------------------------
# PRIVATE FUNCTION - Operations to perform after a single entry has changed state
#--------------------------------------------
entry_state_changed = (id)->
entry = findSvc.find_entry id
entry.changing_state = false if entry?
#--------------------------------------------
# PRIVATE FUNCTION - Operations to perform after multiple entries have changed state
#--------------------------------------------
entries_states_changed = ->
for entry in $rootScope.entries
entry.changing_state = false
timerFlagSvc.start 'success_mark_all_read'
#--------------------------------------------
# PRIVATE FUNCTION - Mark a single entry as read or unread.
# Receives as arguments an entry and a boolean indicating whether to mark
# it as read (true) or unread (false).
#--------------------------------------------
change_entry_state = (entry, read)->
# If entry is already in the requested state, nothing to be done
if entry.read != read
# Mark entry as read or unread in the model
entry.read = read
entry.changing_state = true
if read
state = "read"
changeUnreadCountSvc.update_unread_count entry, false
else
state = "unread"
changeUnreadCountSvc.update_unread_count entry, true
# Change the entry state in a separate thread using a web worker
worker.postMessage {operation: CHANGE_SINGLE_ENTRY, token: token, id: entry.id, state: state}
#--------------------------------------------
# PRIVATE FUNCTION - Set the feed with the passed ID as the currently selected one, and
# load its list of entries
#--------------------------------------------
read_feed = (feed_id)->
feed = findSvc.find_feed feed_id
if feed?
currentFeedSvc.set feed
loadEntriesSvc.read_entries_page()
#--------------------------------------------
# PRIVATE FUNCTION - Mark all entries in the currently selected feed or folder as read.
#--------------------------------------------
change_entries_read = ->
if $rootScope.entries && $rootScope.entries?.length > 0
# Mark entries as read in the model
first_entry = $rootScope.entries[0]
for entry in $rootScope.entries
entry.read = true
entry.changing_state = true
# Find out if the user wants to mark as read a whole feed, a whole folder, or all entries in
# all subscribed feeds.
current_feed = currentFeedSvc.get()
current_folder = currentFolderSvc.get()
if current_feed
whole_feed = "true"
whole_folder = "false"
all_entries = "false"
changeUnreadCountSvc.zero_feed_count current_feed.id
else if current_folder && current_folder?.id != "all"
whole_feed = "false"
whole_folder = "true"
all_entries = "false"
changeUnreadCountSvc.zero_folder_count current_folder
else if current_folder && current_folder?.id == "all"
whole_feed = "false"
whole_folder = "false"
all_entries = "true"
changeUnreadCountSvc.zero_folder_count 'all'
else
return
# Change entries state in a separate thread using a web worker
worker.postMessage {operation: CHANGE_MULTIPLE_ENTRIES, token: token, id: first_entry.id, state: 'read', whole_feed: whole_feed, whole_folder: whole_folder, all_entries: all_entries}
service =
#--------------------------------------------
# Set (if opening) or unset (if closing) the currently open entry. If opening, mark it as read.
# Receives as arguments:
# - entry to be opened or closed
#--------------------------------------------
toggle_open_entry: (entry)->
if entry?
if openEntrySvc.is_open entry
openEntrySvc.close entry
else
openEntrySvc.open entry
change_entry_state entry, true
lazyLoadingSvc.load_entry_images entry
tourSvc.show_entry_tour()
#--------------------------------------------
# Mark a single entry as unread
#--------------------------------------------
read_entry: (entry)->
if entry?
change_entry_state entry, true if !entry.read
#--------------------------------------------
# Mark a single entry as unread
#--------------------------------------------
unread_entry: (entry)->
if entry?
change_entry_state entry, false if entry.read
#--------------------------------------------
# Mark all entries as read
#--------------------------------------------
mark_all_read: ->
animationsSvc.highlight_read_all_button()
menuCollapseSvc.close()
change_entries_read()
#--------------------------------------------
# Return the title of the feed to which an entry belongs
#--------------------------------------------
entry_feed_title: (entry)->
feed = findSvc.find_feed entry.feed_id
if feed
return feed.title
else
# If an entry is retrieved without a corresponding feed in the scope,
# immediately load it from the server
loadFeedsSvc.load_feed entry.feed_id
return ''
return service
]