Added ajax long polling.
This commit is contained in:
parent
f496f82669
commit
5e69e1af4e
13 changed files with 314 additions and 118 deletions
|
@ -8,8 +8,6 @@ class App.DashboardActivityStream extends App.Controller
|
||||||
super
|
super
|
||||||
@items = []
|
@items = []
|
||||||
|
|
||||||
# refresh list ever 140 sec.
|
|
||||||
# @interval( @fetch, 1400000, 'dashboard_activity_stream' )
|
|
||||||
@fetch()
|
@fetch()
|
||||||
|
|
||||||
# bind to rebuild view event
|
# bind to rebuild view event
|
||||||
|
@ -22,17 +20,20 @@ class App.DashboardActivityStream extends App.Controller
|
||||||
if cache
|
if cache
|
||||||
@load( cache )
|
@load( cache )
|
||||||
|
|
||||||
# # get data
|
# init fetch via ajax, all other updates on time via websockets
|
||||||
# App.Com.ajax(
|
else
|
||||||
# id: 'dashoard_activity_stream',
|
App.Com.ajax(
|
||||||
# type: 'GET',
|
id: 'dashoard_activity_stream'
|
||||||
# url: '/api/activity_stream',
|
type: 'GET'
|
||||||
# data: {
|
url: '/api/activity_stream'
|
||||||
# limit: @limit,
|
data: {
|
||||||
# }
|
limit: 8
|
||||||
# processData: true,
|
}
|
||||||
# success: @load
|
processData: true
|
||||||
# )
|
success: (data) =>
|
||||||
|
App.Store.write( 'activity_stream', data )
|
||||||
|
@load(data)
|
||||||
|
)
|
||||||
|
|
||||||
load: (data) =>
|
load: (data) =>
|
||||||
items = data.activity_stream
|
items = data.activity_stream
|
||||||
|
|
|
@ -11,19 +11,42 @@ class App.DashboardRss extends App.Controller
|
||||||
@fetch()
|
@fetch()
|
||||||
|
|
||||||
fetch: =>
|
fetch: =>
|
||||||
|
|
||||||
|
# get data from cache
|
||||||
cache = App.Store.get( 'dashboard_rss' )
|
cache = App.Store.get( 'dashboard_rss' )
|
||||||
if cache
|
if cache
|
||||||
@load( cache )
|
@render( cache )
|
||||||
|
|
||||||
load: (data) =>
|
# init fetch via ajax, all other updates on time via websockets
|
||||||
items = data.items || []
|
else
|
||||||
@head = data.head || '?'
|
App.Com.ajax(
|
||||||
@render(items)
|
id: 'dashboard_rss'
|
||||||
|
type: 'GET'
|
||||||
|
url: '/api/rss_fetch'
|
||||||
|
data: {
|
||||||
|
limit: 8
|
||||||
|
url: 'http://www.heise.de/newsticker/heise-atom.xml'
|
||||||
|
}
|
||||||
|
processData: true
|
||||||
|
success: (data) =>
|
||||||
|
if data.message
|
||||||
|
@render(
|
||||||
|
head: 'Heise ATOM'
|
||||||
|
message: data.message
|
||||||
|
)
|
||||||
|
else
|
||||||
|
App.Store.write( 'dashboard_rss', data )
|
||||||
|
@render(data)
|
||||||
|
error: =>
|
||||||
|
@render(
|
||||||
|
head: 'Heise ATOM'
|
||||||
|
message: 'Unable to fetch rss!'
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
render: (items) ->
|
render: (data) ->
|
||||||
html = App.view('dashboard/rss')(
|
@html App.view('dashboard/rss')(
|
||||||
head: @head,
|
head: data.head,
|
||||||
items: items
|
items: data.item || []
|
||||||
|
message: data.message
|
||||||
)
|
)
|
||||||
html = $(html)
|
|
||||||
@html html
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ class App.DashboardTicket extends App.Controller
|
||||||
|
|
||||||
constructor: ->
|
constructor: ->
|
||||||
super
|
super
|
||||||
@start_page = 1
|
@start_page = 1
|
||||||
@navupdate '#'
|
@navupdate '#'
|
||||||
|
|
||||||
# set new key
|
# set new key
|
||||||
|
@ -25,25 +25,37 @@ class App.DashboardTicket extends App.Controller
|
||||||
# use cache of first page
|
# use cache of first page
|
||||||
cache = App.Store.get( @key )
|
cache = App.Store.get( @key )
|
||||||
if cache
|
if cache
|
||||||
# @render( cache )
|
|
||||||
@load( cache )
|
@load( cache )
|
||||||
|
|
||||||
# get data
|
# init fetch via ajax, all other updates on time via websockets
|
||||||
# App.Com.ajax(
|
else
|
||||||
# id: 'dashboard_ticket_' + @key,
|
App.Com.ajax(
|
||||||
# type: 'GET',
|
id: 'dashboard_ticket_' + @key,
|
||||||
# url: '/api/ticket_overviews',
|
type: 'GET',
|
||||||
# data: {
|
url: '/api/ticket_overviews',
|
||||||
# view: @view,
|
data: {
|
||||||
# view_mode: 'd',
|
view: @view,
|
||||||
# start_page: @start_page,
|
view_mode: 'd',
|
||||||
# }
|
start_page: @start_page,
|
||||||
# processData: true,
|
}
|
||||||
# success: @load
|
processData: true,
|
||||||
# )
|
success: (data) =>
|
||||||
|
data.ajax = true
|
||||||
|
@load(data)
|
||||||
|
)
|
||||||
|
|
||||||
load: (data) =>
|
load: (data) =>
|
||||||
|
|
||||||
|
if data.ajax
|
||||||
|
data.ajax = false
|
||||||
|
App.Store.write( @key, data )
|
||||||
|
|
||||||
|
# load user collection
|
||||||
|
App.Collection.load( type: 'User', data: data.collections.users )
|
||||||
|
|
||||||
|
# load ticket collection
|
||||||
|
App.Collection.load( type: 'Ticket', data: data.collections.tickets )
|
||||||
|
|
||||||
# get meta data
|
# get meta data
|
||||||
App.Overview.refresh( data.overview, options: { clear: true } )
|
App.Overview.refresh( data.overview, options: { clear: true } )
|
||||||
|
|
||||||
|
@ -57,11 +69,12 @@ class App.DashboardTicket extends App.Controller
|
||||||
@log 'refetch...', record
|
@log 'refetch...', record
|
||||||
@fetch()
|
@fetch()
|
||||||
|
|
||||||
# App.Store.write( @key, data )
|
|
||||||
|
|
||||||
@render( data )
|
@render( data )
|
||||||
|
|
||||||
render: (data) ->
|
render: (data) ->
|
||||||
|
return if !data
|
||||||
|
return if !data.ticket_list
|
||||||
|
return if !data.overview
|
||||||
|
|
||||||
@overview = data.overview
|
@overview = data.overview
|
||||||
@tickets_count = data.tickets_count
|
@tickets_count = data.tickets_count
|
||||||
|
|
|
@ -37,12 +37,42 @@ class Index extends App.Controller
|
||||||
# use cache of first page
|
# use cache of first page
|
||||||
cache = App.Store.get( @key )
|
cache = App.Store.get( @key )
|
||||||
if cache
|
if cache
|
||||||
@overview = cache.overview
|
|
||||||
@tickets_count = cache.tickets_count
|
|
||||||
@ticket_list = cache.ticket_list
|
|
||||||
@load(cache)
|
@load(cache)
|
||||||
|
|
||||||
|
# init fetch via ajax, all other updates on time via websockets
|
||||||
|
else
|
||||||
|
App.Com.ajax(
|
||||||
|
id: 'ticket_overview_' + @key,
|
||||||
|
type: 'GET',
|
||||||
|
url: '/api/ticket_overviews',
|
||||||
|
data: {
|
||||||
|
view: @view,
|
||||||
|
view_mode: @view_mode,
|
||||||
|
}
|
||||||
|
processData: true,
|
||||||
|
success: (data) =>
|
||||||
|
data.ajax = true
|
||||||
|
@load(data)
|
||||||
|
)
|
||||||
|
|
||||||
load: (data) =>
|
load: (data) =>
|
||||||
|
return if !data
|
||||||
|
return if !data.ticket_list
|
||||||
|
return if !data.overview
|
||||||
|
|
||||||
|
@overview = data.overview
|
||||||
|
@tickets_count = data.tickets_count
|
||||||
|
@ticket_list = data.ticket_list
|
||||||
|
|
||||||
|
if data.ajax
|
||||||
|
data.ajax = false
|
||||||
|
App.Store.write( @key, data )
|
||||||
|
|
||||||
|
# load user collection
|
||||||
|
App.Collection.load( type: 'User', data: data.collections.users )
|
||||||
|
|
||||||
|
# load ticket collection
|
||||||
|
App.Collection.load( type: 'Ticket', data: data.collections.tickets )
|
||||||
|
|
||||||
# get meta data
|
# get meta data
|
||||||
@overview = data.overview
|
@overview = data.overview
|
||||||
|
|
|
@ -5,9 +5,7 @@ class App.Com
|
||||||
@ajax: (args) -> # Must be a static method
|
@ajax: (args) -> # Must be a static method
|
||||||
if _instance == undefined
|
if _instance == undefined
|
||||||
_instance ?= new _Singleton
|
_instance ?= new _Singleton
|
||||||
|
|
||||||
_instance.ajax(args)
|
_instance.ajax(args)
|
||||||
_instance
|
|
||||||
|
|
||||||
# The actual Singleton class
|
# The actual Singleton class
|
||||||
class _Singleton
|
class _Singleton
|
||||||
|
|
|
@ -9,7 +9,7 @@ class App.WebSocket
|
||||||
|
|
||||||
@close: (args) -> # Must be a static method
|
@close: (args) -> # Must be a static method
|
||||||
if _instance isnt undefined
|
if _instance isnt undefined
|
||||||
_instance.close()
|
_instance.close(args)
|
||||||
|
|
||||||
@send: (args) -> # Must be a static method
|
@send: (args) -> # Must be a static method
|
||||||
@connect()
|
@connect()
|
||||||
|
@ -20,6 +20,7 @@ class App.WebSocket
|
||||||
_instance.auth(args)
|
_instance.auth(args)
|
||||||
|
|
||||||
@_spool: ->
|
@_spool: ->
|
||||||
|
@connect()
|
||||||
_instance.spool()
|
_instance.spool()
|
||||||
|
|
||||||
# The actual Singleton class
|
# The actual Singleton class
|
||||||
|
@ -27,9 +28,12 @@ class _Singleton extends App.Controller
|
||||||
@include App.Log
|
@include App.Log
|
||||||
|
|
||||||
queue: []
|
queue: []
|
||||||
supported: true
|
supported: true
|
||||||
lastSpoolMessage: undefined
|
lastSpoolMessage: undefined
|
||||||
connectionEstablished: false
|
connectionEstablished: false
|
||||||
|
connectionWasEstablished: false
|
||||||
|
backend: 'websocket'
|
||||||
|
client_id: undefined
|
||||||
|
|
||||||
constructor: (@args) ->
|
constructor: (@args) ->
|
||||||
|
|
||||||
|
@ -46,19 +50,22 @@ class _Singleton extends App.Controller
|
||||||
@connect()
|
@connect()
|
||||||
|
|
||||||
send: (data) =>
|
send: (data) =>
|
||||||
return if !@supported
|
if @backend is 'ajax'
|
||||||
# console.log 'ws:send trying', data, @ws, @ws.readyState
|
@_ajaxSend(data)
|
||||||
|
|
||||||
# A value of 0 indicates that the connection has not yet been established.
|
|
||||||
# A value of 1 indicates that the connection is established and communication is possible.
|
|
||||||
# A value of 2 indicates that the connection is going through the closing handshake.
|
|
||||||
# A value of 3 indicates that the connection has been closed or could not be opened.
|
|
||||||
if @ws.readyState is 0
|
|
||||||
@queue.push data
|
|
||||||
else
|
else
|
||||||
# console.log( 'ws:send', data )
|
|
||||||
string = JSON.stringify( data )
|
# console.log 'ws:send trying', data, @ws, @ws.readyState
|
||||||
@ws.send(string)
|
|
||||||
|
# A value of 0 indicates that the connection has not yet been established.
|
||||||
|
# A value of 1 indicates that the connection is established and communication is possible.
|
||||||
|
# A value of 2 indicates that the connection is going through the closing handshake.
|
||||||
|
# A value of 3 indicates that the connection has been closed or could not be opened.
|
||||||
|
if @ws.readyState is 0
|
||||||
|
@queue.push data
|
||||||
|
else
|
||||||
|
# console.log( 'ws:send', data )
|
||||||
|
string = JSON.stringify( data )
|
||||||
|
@ws.send(string)
|
||||||
|
|
||||||
auth: (data) =>
|
auth: (data) =>
|
||||||
return if !@supported
|
return if !@supported
|
||||||
|
@ -77,7 +84,7 @@ class _Singleton extends App.Controller
|
||||||
if @lastSpoolMessage
|
if @lastSpoolMessage
|
||||||
data['timestamp'] = @lastSpoolMessage
|
data['timestamp'] = @lastSpoolMessage
|
||||||
|
|
||||||
@log 'Event', 'debug', 'spool', data
|
@log 'Websocket', 'debug', 'spool', data
|
||||||
|
|
||||||
# ask for spool messages
|
# ask for spool messages
|
||||||
App.Event.trigger(
|
App.Event.trigger(
|
||||||
|
@ -89,37 +96,38 @@ class _Singleton extends App.Controller
|
||||||
@lastSpoolMessage = Math.round( +new Date()/1000 )
|
@lastSpoolMessage = Math.round( +new Date()/1000 )
|
||||||
|
|
||||||
close: =>
|
close: =>
|
||||||
return if !@supported
|
return if @backend is 'ajax'
|
||||||
|
|
||||||
@ws.close()
|
@ws.close()
|
||||||
|
|
||||||
ping: =>
|
ping: =>
|
||||||
return if !@supported
|
return if @backend is 'ajax'
|
||||||
|
|
||||||
@log 'Event', 'debug', 'send websockend ping'
|
@log 'Websocket', 'debug', 'send websockend ping'
|
||||||
@send( { action: 'ping' } )
|
@send( { action: 'ping' } )
|
||||||
|
|
||||||
# check if ping is back within 2 min
|
# check if ping is back within 2 min
|
||||||
@clearDelay('websocket-ping-check')
|
@clearDelay('websocket-ping-check')
|
||||||
check = =>
|
check = =>
|
||||||
@log 'Event', 'notice', 'no websockend ping response, reconnect...'
|
@log 'Websocket', 'notice', 'no websockend ping response, reconnect...'
|
||||||
@close()
|
@close()
|
||||||
@delay check, 120000, 'websocket-ping-check'
|
@delay check, 120000, 'websocket-ping-check'
|
||||||
|
|
||||||
pong: ->
|
pong: ->
|
||||||
return if !@supported
|
return if @backend is 'ajax'
|
||||||
@log 'Event', 'debug', 'received websockend ping'
|
|
||||||
|
@log 'Websocket', 'debug', 'received websockend ping'
|
||||||
|
|
||||||
# test again after 1 min
|
# test again after 1 min
|
||||||
@delay @ping, 60000
|
@delay @ping, 60000
|
||||||
|
|
||||||
connect: =>
|
connect: =>
|
||||||
|
return if @backend is 'ajax'
|
||||||
|
|
||||||
if !window.WebSocket
|
if !window.WebSocket
|
||||||
@error = new App.ErrorModal(
|
@backend = 'ajax'
|
||||||
message: 'Sorry, no websocket support!'
|
@log 'WebSocket', 'notice', 'no support of websocket, use ajax long polling'
|
||||||
)
|
@_ajaxInit()
|
||||||
@supported = false
|
|
||||||
return
|
return
|
||||||
|
|
||||||
protocol = 'ws://'
|
protocol = 'ws://'
|
||||||
|
@ -130,9 +138,10 @@ class _Singleton extends App.Controller
|
||||||
|
|
||||||
# Set event handlers.
|
# Set event handlers.
|
||||||
@ws.onopen = =>
|
@ws.onopen = =>
|
||||||
@log 'Event', 'notice', 'new websocked connection open'
|
@log 'Websocket', 'notice', 'new websocket connection open'
|
||||||
|
|
||||||
@connectionEstablished = true
|
@connectionEstablished = true
|
||||||
|
@connectionWasEstablished = true
|
||||||
|
|
||||||
# close error message show up (because try so connect again) if exists
|
# close error message show up (because try so connect again) if exists
|
||||||
@clearDelay('websocket-no-connection-try-reconnect')
|
@clearDelay('websocket-no-connection-try-reconnect')
|
||||||
|
@ -144,7 +153,7 @@ class _Singleton extends App.Controller
|
||||||
|
|
||||||
# empty queue
|
# empty queue
|
||||||
for item in @queue
|
for item in @queue
|
||||||
@log 'Event', 'debug', 'empty ws queue', item
|
@log 'Websocket', 'debug', 'empty ws queue', item
|
||||||
@send(item)
|
@send(item)
|
||||||
@queue = []
|
@queue = []
|
||||||
|
|
||||||
|
@ -153,41 +162,31 @@ class _Singleton extends App.Controller
|
||||||
|
|
||||||
@ws.onmessage = (e) =>
|
@ws.onmessage = (e) =>
|
||||||
pipe = JSON.parse( e.data )
|
pipe = JSON.parse( e.data )
|
||||||
@log 'Event', 'debug', 'ws:onmessage', pipe
|
@log 'Websocket', 'debug', 'ws:onmessage', pipe
|
||||||
|
@_receiveMessage(pipe)
|
||||||
# go through all blocks
|
|
||||||
for item in pipe
|
|
||||||
|
|
||||||
# reset reconnect loop
|
|
||||||
if item['action'] is 'pong'
|
|
||||||
@pong()
|
|
||||||
|
|
||||||
# fill collection
|
|
||||||
if item['collection']
|
|
||||||
@log 'Event', 'debug', "ws:onmessage collection:" + item['collection']
|
|
||||||
App.Store.write( item['collection'], item['data'] )
|
|
||||||
|
|
||||||
# fire event
|
|
||||||
if item['event']
|
|
||||||
if typeof item['event'] is 'object'
|
|
||||||
for event in item['event']
|
|
||||||
@log 'Event', 'debug', "ws:onmessage event:" + event
|
|
||||||
App.Event.trigger( event, item['data'] )
|
|
||||||
else
|
|
||||||
@log 'Event', 'debug', "ws:onmessage event:" + item['event']
|
|
||||||
App.Event.trigger( item['event'], item['data'] )
|
|
||||||
|
|
||||||
@ws.onclose = (e) =>
|
@ws.onclose = (e) =>
|
||||||
@log 'Event', 'debug', "ws:onclose", e
|
@log 'Websocket', 'debug', "ws:onclose", e
|
||||||
|
|
||||||
# set timestamp to get spool messages later
|
# set timestamp to get spool messages later
|
||||||
if @connectionEstablished
|
if @connectionEstablished
|
||||||
@lastSpoolMessage = Math.round( +new Date()/1000 )
|
@lastSpoolMessage = Math.round( +new Date()/1000 )
|
||||||
@connectionEstablished = false
|
@connectionEstablished = false
|
||||||
|
|
||||||
|
return if @backend is 'ajax'
|
||||||
|
|
||||||
# show error message, first try to reconnect
|
# show error message, first try to reconnect
|
||||||
if !@error
|
if !@error
|
||||||
message = =>
|
message = =>
|
||||||
|
|
||||||
|
# use fallback if no connection was possible
|
||||||
|
if !@connectionWasEstablished
|
||||||
|
@backend = 'ajax'
|
||||||
|
@log 'WebSocket', 'notice', 'No connection to websocket, use use ajax long polling as fallback'
|
||||||
|
@_ajaxInit()
|
||||||
|
return
|
||||||
|
|
||||||
|
# show reconnect message
|
||||||
@error = new App.ErrorModal(
|
@error = new App.ErrorModal(
|
||||||
message: 'No connection to websocket, trying to reconnect...'
|
message: 'No connection to websocket, trying to reconnect...'
|
||||||
)
|
)
|
||||||
|
@ -197,5 +196,110 @@ class _Singleton extends App.Controller
|
||||||
@delay @connect, 4500
|
@delay @connect, 4500
|
||||||
|
|
||||||
@ws.onerror = (e) =>
|
@ws.onerror = (e) =>
|
||||||
@log 'Event', 'debug', "ws:onerror", e
|
@log 'Websocket', 'debug', "ws:onerror", e
|
||||||
|
|
||||||
|
_receiveMessage: (data = []) =>
|
||||||
|
|
||||||
|
# go through all blocks
|
||||||
|
for item in data
|
||||||
|
|
||||||
|
# reset reconnect loop
|
||||||
|
if item['action'] is 'pong'
|
||||||
|
@pong()
|
||||||
|
|
||||||
|
# fill collection
|
||||||
|
if item['collection']
|
||||||
|
@log 'Websocket', 'debug', "onmessage collection:" + item['collection']
|
||||||
|
App.Store.write( item['collection'], item['data'] )
|
||||||
|
|
||||||
|
# fire event
|
||||||
|
if item['event']
|
||||||
|
if typeof item['event'] is 'object'
|
||||||
|
for event in item['event']
|
||||||
|
@log 'Websocket', 'debug', "onmessage event:" + event
|
||||||
|
App.Event.trigger( event, item['data'] )
|
||||||
|
else
|
||||||
|
@log 'Websocket', 'debug', "onmessage event:" + item['event']
|
||||||
|
App.Event.trigger( item['event'], item['data'] )
|
||||||
|
|
||||||
|
_ajaxInit: (data = {}) =>
|
||||||
|
|
||||||
|
# return if init is already done and not forced
|
||||||
|
return if @_ajaxInitDone && !data.force
|
||||||
|
|
||||||
|
# stop init request if new one is started
|
||||||
|
if @_ajaxInitWorking
|
||||||
|
console.log '@_ajaxInitWorking', @_ajaxInitWorking
|
||||||
|
@_ajaxInitWorking.abort()
|
||||||
|
|
||||||
|
# call init request
|
||||||
|
@_ajaxInitWorking = App.Com.ajax(
|
||||||
|
type: 'POST'
|
||||||
|
url: '/api/message_send'
|
||||||
|
data: JSON.stringify({ data: { action: 'login' } })
|
||||||
|
processData: false
|
||||||
|
queue: false
|
||||||
|
success: (data) =>
|
||||||
|
if data.client_id
|
||||||
|
@log 'Websocket', 'notice', 'ajax:new client_id', data.client_id
|
||||||
|
@client_id = data.client_id
|
||||||
|
@_ajaxReceive()
|
||||||
|
@_ajaxSendQueue()
|
||||||
|
@_ajaxInitDone = true
|
||||||
|
@_ajaxInitWorking = false
|
||||||
|
error: =>
|
||||||
|
@_ajaxInitDone = true
|
||||||
|
@_ajaxInitWorking = false
|
||||||
|
)
|
||||||
|
|
||||||
|
_ajaxSend: (data) =>
|
||||||
|
@log 'Websocket', 'debug', 'ajax:sendmessage', data
|
||||||
|
if !@client_id || @client_id is undefined || !@_ajaxInitDone
|
||||||
|
@_ajaxInit()
|
||||||
|
@queue.push data
|
||||||
|
else
|
||||||
|
@queue.push data
|
||||||
|
@_ajaxSendQueue()
|
||||||
|
|
||||||
|
_ajaxSendQueue: =>
|
||||||
|
while !_.isEmpty(@queue)
|
||||||
|
data = @queue.shift()
|
||||||
|
App.Com.ajax(
|
||||||
|
type: 'POST'
|
||||||
|
url: '/api/message_send'
|
||||||
|
data: JSON.stringify({ client_id: @client_id, data: data })
|
||||||
|
processData: false
|
||||||
|
queue: true
|
||||||
|
success: (data) =>
|
||||||
|
if data && data.error
|
||||||
|
@client_id = undefined
|
||||||
|
@_ajaxInit( force: true )
|
||||||
|
error: =>
|
||||||
|
@client_id = undefined
|
||||||
|
@_ajaxInit( force: true )
|
||||||
|
)
|
||||||
|
|
||||||
|
_ajaxReceive: =>
|
||||||
|
return if !@client_id
|
||||||
|
return if @_ajaxReceiveWorking is true
|
||||||
|
@_ajaxReceiveWorking = true
|
||||||
|
App.Com.ajax(
|
||||||
|
id: 'message_receive',
|
||||||
|
type: 'POST'
|
||||||
|
url: '/api/message_receive'
|
||||||
|
data: JSON.stringify({ client_id: @client_id })
|
||||||
|
processData: false
|
||||||
|
success: (data) =>
|
||||||
|
@log 'Websocket', 'notice', 'ajax:onmessage', data
|
||||||
|
@_receiveMessage(data)
|
||||||
|
if data && data.error
|
||||||
|
@client_id = undefined
|
||||||
|
@_ajaxInit( force: true )
|
||||||
|
@_ajaxReceiveWorking = false
|
||||||
|
@_ajaxReceive()
|
||||||
|
error: (data) =>
|
||||||
|
@client_id = undefined
|
||||||
|
@_ajaxInit( force: true )
|
||||||
|
@_ajaxReceiveWorking = false
|
||||||
|
@delay @_ajaxReceive, 5000
|
||||||
|
)
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="span3 can-move">
|
<div class="span3 can-move">
|
||||||
<h2><%- @T( @head ) %></h2>
|
<h2><%- @T( @head ) %></h2>
|
||||||
|
<% if @message: %>
|
||||||
|
<%- @T(@message) %>
|
||||||
|
<% end %>
|
||||||
<ul>
|
<ul>
|
||||||
<% for item in @items: %>
|
<% for item in @items: %>
|
||||||
<li><a href="<%= item.link %>" title="<%= item.summary %>" target="_blank"><%= item.title %>"</a></li>
|
<li><a href="<%= item.link %>" title="<%= item.summary %>" target="_blank"><%= item.title %>"</a></li>
|
||||||
|
|
|
@ -3,7 +3,7 @@ class ActivityController < ApplicationController
|
||||||
|
|
||||||
# GET /api/activity_stream
|
# GET /api/activity_stream
|
||||||
def activity_stream
|
def activity_stream
|
||||||
activity_stream = History.activity_stream_fulldata(current_user, params[:limit])
|
activity_stream = History.activity_stream_fulldata( current_user, params[:limit] )
|
||||||
|
|
||||||
# return result
|
# return result
|
||||||
render :json => activity_stream
|
render :json => activity_stream
|
||||||
|
|
|
@ -20,6 +20,7 @@ curl http://localhost/api/rss_fetch.json -v -u #{login}:#{password} -H "Content-
|
||||||
items = RSS.fetch(params[:url], params[:limit])
|
items = RSS.fetch(params[:url], params[:limit])
|
||||||
if items == nil
|
if items == nil
|
||||||
render :json => { :message => "failed to fetch #{ params[:url] }", :status => :unprocessable_entity }
|
render :json => { :message => "failed to fetch #{ params[:url] }", :status => :unprocessable_entity }
|
||||||
|
return
|
||||||
end
|
end
|
||||||
render :json => { :items => items }
|
render :json => { :items => items }
|
||||||
end
|
end
|
||||||
|
|
|
@ -22,8 +22,8 @@ class TicketOverviewsController < ApplicationController
|
||||||
:array => true,
|
:array => true,
|
||||||
)
|
)
|
||||||
tickets = []
|
tickets = []
|
||||||
overview[:tickets].each {|ticket|
|
overview[:tickets].each {|ticket_id|
|
||||||
data = { :id => ticket.id }
|
data = { :id => ticket_id }
|
||||||
tickets.push data
|
tickets.push data
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,18 +36,21 @@ class TicketOverviewsController < ApplicationController
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
overview = Ticket.overview(
|
overview = Ticket.overview(
|
||||||
:view => params[:view],
|
:view => params[:view],
|
||||||
:view_mode => params[:view_mode],
|
# :view_mode => params[:view_mode],
|
||||||
:current_user_id => current_user.id,
|
:current_user => User.find( current_user.id ),
|
||||||
:start_page => params[:start_page],
|
:array => true,
|
||||||
:array => true,
|
|
||||||
)
|
)
|
||||||
|
if !overview
|
||||||
|
render :json => { :error => "No such view #{ params[:view] }!" }, :status => :unprocessable_entity
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
# get related users
|
# get related users
|
||||||
users = {}
|
users = {}
|
||||||
tickets = []
|
tickets = []
|
||||||
overview[:tickets].each {|ticket|
|
overview[:ticket_list].each {|ticket_id|
|
||||||
data = Ticket.full_data(ticket.id)
|
data = Ticket.full_data(ticket_id)
|
||||||
tickets.push data
|
tickets.push data
|
||||||
if !users[ data['owner_id'] ]
|
if !users[ data['owner_id'] ]
|
||||||
users[ data['owner_id'] ] = User.user_data_full( data['owner_id'] )
|
users[ data['owner_id'] ] = User.user_data_full( data['owner_id'] )
|
||||||
|
@ -84,12 +87,15 @@ class TicketOverviewsController < ApplicationController
|
||||||
# return result
|
# return result
|
||||||
render :json => {
|
render :json => {
|
||||||
:overview => overview[:overview],
|
:overview => overview[:overview],
|
||||||
:tickets => tickets,
|
:ticket_list => overview[:ticket_list],
|
||||||
:tickets_count => overview[:tickets_count],
|
:tickets_count => overview[:tickets_count],
|
||||||
:users => users,
|
|
||||||
:bulk => {
|
:bulk => {
|
||||||
:group_id__owner_id => groups_users,
|
:group_id__owner_id => groups_users,
|
||||||
},
|
},
|
||||||
|
:collections => {
|
||||||
|
:users => users,
|
||||||
|
:tickets => tickets,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -217,6 +217,10 @@ class Ticket < ApplicationModel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if data[:view] && !overview_selected
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
# sortby
|
# sortby
|
||||||
# prio
|
# prio
|
||||||
# state
|
# state
|
||||||
|
@ -290,7 +294,7 @@ class Ticket < ApplicationModel
|
||||||
count()
|
count()
|
||||||
|
|
||||||
return {
|
return {
|
||||||
:tickets => ticket_ids,
|
:ticket_list => ticket_ids,
|
||||||
:tickets_count => tickets_count,
|
:tickets_count => tickets_count,
|
||||||
:overview => overview_selected_raw,
|
:overview => overview_selected_raw,
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,7 @@ module RSS
|
||||||
rescue Exception => e
|
rescue Exception => e
|
||||||
puts "can't fetch #{url}"
|
puts "can't fetch #{url}"
|
||||||
puts e.inspect
|
puts e.inspect
|
||||||
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
return items
|
return items
|
||||||
|
|
|
@ -40,6 +40,16 @@ module Session
|
||||||
return session_list
|
return session_list
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def self.touch( client_id )
|
||||||
|
data = self.get(client_id)
|
||||||
|
path = @path + '/' + client_id.to_s
|
||||||
|
data[:meta][:last_ping] = Time.new.to_i.to_s
|
||||||
|
File.open( path + '/session', 'w' ) { |file|
|
||||||
|
file.puts Marshal.dump(data)
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
def self.get( client_id )
|
def self.get( client_id )
|
||||||
session_file = @path + '/' + client_id.to_s + '/session'
|
session_file = @path + '/' + client_id.to_s + '/session'
|
||||||
data = nil
|
data = nil
|
||||||
|
@ -105,6 +115,7 @@ module Session
|
||||||
@@user_threads[user.id] = Thread.new {
|
@@user_threads[user.id] = Thread.new {
|
||||||
UserState.new(user.id)
|
UserState.new(user.id)
|
||||||
@@user_threads[user.id] = nil
|
@@user_threads[user.id] = nil
|
||||||
|
puts "close user(#{user.id}) thread"
|
||||||
# raise "Exception from thread"
|
# raise "Exception from thread"
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
@ -119,13 +130,14 @@ module Session
|
||||||
@@client_threads[client_id] = Thread.new {
|
@@client_threads[client_id] = Thread.new {
|
||||||
ClientState.new(client_id)
|
ClientState.new(client_id)
|
||||||
@@client_threads[client_id] = nil
|
@@client_threads[client_id] = nil
|
||||||
|
puts "close client(#{client_id}) thread"
|
||||||
# raise "Exception from thread"
|
# raise "Exception from thread"
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
|
|
||||||
# system settings
|
# system settings
|
||||||
sleep 0.4
|
sleep 0.5
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -464,7 +476,7 @@ class ClientState
|
||||||
self.log 'notify', "push overview_data #{overview.meta[:url]} for user #{user.id}"
|
self.log 'notify', "push overview_data #{overview.meta[:url]} for user #{user.id}"
|
||||||
users = {}
|
users = {}
|
||||||
tickets = []
|
tickets = []
|
||||||
overview_data[:tickets].each {|ticket_id|
|
overview_data[:ticket_list].each {|ticket_id|
|
||||||
self.ticket( ticket_id, tickets, users )
|
self.ticket( ticket_id, tickets, users )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -494,7 +506,7 @@ class ClientState
|
||||||
self.send({
|
self.send({
|
||||||
:data => {
|
:data => {
|
||||||
:overview => overview_data[:overview],
|
:overview => overview_data[:overview],
|
||||||
:ticket_list => overview_data[:tickets],
|
:ticket_list => overview_data[:ticket_list],
|
||||||
:tickets_count => overview_data[:tickets_count],
|
:tickets_count => overview_data[:tickets_count],
|
||||||
:collections => {
|
:collections => {
|
||||||
:User => users,
|
:User => users,
|
||||||
|
|
Loading…
Reference in a new issue