Skip to content

Commit

Permalink
Merge pull request #81 from it3s/news_feed
Browse files Browse the repository at this point in the history
News feed
  • Loading branch information
andersoncardoso committed Sep 26, 2014
2 parents db9f650 + d97c83b commit a4bf1c6
Show file tree
Hide file tree
Showing 25 changed files with 452 additions and 36 deletions.
9 changes: 8 additions & 1 deletion app/assets/javascripts/base.js.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ componentBuilder = (name, container) ->
"#{name}:#{_id}"

start: ->
if not components[name]?
console?.error "Component not found: #{name}"
return
console?.log "Starting Component: #{name}"
_comp = components[name]()
_comp.container = container
_comp.identifier = @compId()
Expand Down Expand Up @@ -66,7 +70,10 @@ componentsManager = (container) ->
@onStarted()

startComponents = (evt, root=document) ->
$(root).find('[data-components]').each (i, container) =>
attr = 'data-components'
$root = $ root
componentsManager($root).buildComponents() if $root.attr(attr)
$root.find("[#{attr}]").each (i, container) =>
componentsManager($(container)).buildComponents()

mediator.subscribe 'components:start', startComponents
Expand Down
96 changes: 96 additions & 0 deletions app/assets/javascripts/components/selector.js.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
App.components.selector = ->
initialize: ->
@baseURL = @attr.url ? "#{window.location.pathname}"
@getQueryValues()
@getParams()
@updateValues()
@bindEvents()
@updateDisplay()

getQueryValues: ->
@queryValues = _.reduce(window.location.search.substr(1).split('&'), (ret, param) ->
parts = param.replace(/\+/g, ' ').split('=')
key = decodeURIComponent(parts[0])
val = parts[1]
val = if not val? then null else decodeURIComponent(val)
if not ret[key]?
ret[key] = val
else if _.isArray ret[key]
ret[key].push val
else
ret[key] = [ret[key], val]
return ret
, {})

getParams: ->
selectors = $(".options")
@params ?= {}
for selector in selectors
selector = $ selector
paramName = selector.data "selector-param"
defaultValue = selector.find('.option[data-selector-default]').data "selector-value"
@params[paramName] ?=
name: paramName
selector: selector
default: defaultValue
value: @queryValues[paramName]
@params

updateValue: (param) ->
value = param.value ? param.default
selectedOption = param.selector.find(".option").filter ->
$(this).data("selector-selected") is true
value = selectedOption.data "selector-value" if selectedOption.length > 0
param.value = value

updateValues: ->
for paramName, param of @params
@updateValue param

updateDisplay: ->
for paramName, param of @params
param.selector.find(".option").each (idx, el) ->
el = $ el
selected = el.data("selector-value") is param.value
el.data "selector-selected", selected
if not selected then el.removeClass("selected") else el.addClass("selected")

changeValue: (param, value) ->
return if param.value is value
param.value = value
App.mediator.publish "selector:changed", @getURLParams()
@loadURL() if @attr.autoload
@updateDisplay()

bindEvents: ->
that = this
for paramName, param of @params
param.selector.find(".option").click ((param) ->
(evt) ->
evt.preventDefault()
value = $(this).data "selector-value"
that.changeValue param, value
)(param)

onSuccess: (data) ->
content = $(data).find(@attr.target)
$(@attr.target).replaceWith content
App.mediator.publish "components:start", content
App.utils.spinner.hide()

getURLParams: ->
params = {}
for paramName, param of @params
params[paramName] = param.value if param.value?
params

getURL: ->
params = $.param @getURLParams()
"#{@baseURL}?#{params}#{window.location.hash}"

loadURL: ->
App.utils.spinner.show()
if @attr.remote
$.get @getURL(), @onSuccess.bind(this)
else
window.location = @getURL()
16 changes: 15 additions & 1 deletion app/assets/stylesheets/activities.css.scss
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,13 @@
}
}

.event-owner,
.event-type {
font-weight: bold;
}

.activity-event {
display: inline-block;
display: inline;
}

.activity-time {
Expand All @@ -34,6 +35,19 @@
margin-left: 10px;
}

.owner-avatar {
display: inline-block;
float: left;
margin: -3px 6px 0 -22px;
position: relative;

img {
border: $white 1px solid;
width: 22px;
height: 22px;
}
}

.activity-changes {
margin-top: 5px;
font-size: 0.9em;
Expand Down
15 changes: 12 additions & 3 deletions app/assets/stylesheets/pages/_frontpage.css.scss
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@
h3{ text-indent: 5px; }
}

li {
.blog li {
:hover { background: $meppit-light-blue; }
a {
display: block;
Expand All @@ -162,10 +162,19 @@
img { margin-right: 0.2em }
}

.last_updates .updates {
.last_updates {
margin: 0;

li a { margin-bottom: 0; }
#activity {
height: 310px;
overflow-y: auto;
}

.activities-list {
.list-item {
&.small .item { width: 350px; }
}
}
}

.apart {
Expand Down
7 changes: 5 additions & 2 deletions app/assets/stylesheets/shared/_export.css.scss
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,11 @@

.help { margin-top: 20px;}

.option {
width: 89.5px;
.options {
width: 100%;
.option {
width: 25%;
}
}
}
#export-help {
Expand Down
78 changes: 59 additions & 19 deletions app/assets/stylesheets/shared/_options.css.scss
Original file line number Diff line number Diff line change
@@ -1,21 +1,61 @@
.option {
display: inline-block;
cursor: pointer;
text-align: center;
margin: 0 5px;
padding: 20px 0;
font-size: 1.2em;
font-weight: bold;
text-decoration: none;
color: white;
background-color: $meppit-dark-blue;
border-radius: 5px;
border: solid 1px $meppit-data-color;

&:first-child { margin-left: 0;}
&:last-child { margin-right: 0;}

&:hover {
background-color: lighten($meppit-dark-blue, 10%);
.options {
display: table;
min-height: 60px;
border-spacing: 5px;

.option {
display: table-cell;
cursor: pointer;
text-align: center;
margin: 0 5px;
padding: 5px;
font-size: 1.2em;
font-weight: bold;
text-decoration: none;
color: white;
background-color: $meppit-dark-blue;
border-radius: 5px;
border: solid 1px $meppit-data-color;
vertical-align: middle;

&:first-child { margin-left: 0;}
&:last-child { margin-right: 0;}

&:hover {
background-color: lighten($meppit-dark-blue, 10%);
border: solid 1px $meppit-data-color;
}
}
}

.selector {
margin: 10px 0;

.options-label {
font-weight: bold;
}

.options-label,
.options-container {
display: inline-block;
vertical-align: middle;
}

.options {
min-height: 40px;

.option {
color: $medium-grey;
background-color: $ultra-soft-grey;
border: solid 1px $soft-grey;
font-weight: normal;
padding: 10px;

&.selected {
color: $white;
background-color: $meppit-dark-blue;
border: solid 1px $meppit-data-color;
}
}
}
}
6 changes: 6 additions & 0 deletions app/controllers/activities_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ def user_activity
render layout: nil if request.xhr?
end

def news_feed
all = (params[:display] == 'all')
@activities = news_feed_results all
render layout: nil if request.xhr?
end

private

def find_user
Expand Down
9 changes: 9 additions & 0 deletions app/controllers/concerns/utils.rb
Original file line number Diff line number Diff line change
Expand Up @@ -102,5 +102,14 @@ def flash_xhr(msg)
flash.now[:notice] = msg
render_to_string(partial: 'shared/alerts')
end

def news_feed_results(all=false)
if all || !current_user
activities = paginate PublicActivity::Activity.order('created_at desc').includes(:trackable, :owner)
else
activities = paginate current_user.following_activities.includes(:owner)
end
activities
end
end

1 change: 1 addition & 0 deletions app/controllers/pages_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

class PagesController < ApplicationController
def frontpage
@activities = news_feed_results
@news = news
end

Expand Down
7 changes: 7 additions & 0 deletions app/helpers/concerns/components_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,13 @@ def autocomplete_field_tag(name, url)
render('shared/components/autocomplete', name: name, url: url).html_safe
end

def selector_option(label, param, value, default=false, class_name=nil)
class_name = value unless class_name
selected = params[param] == value.to_s || (params[param].nil? && default)
"<a href=\"?#{param}=#{value}\" class=\"option #{class_name}#{' selected' if selected}\" data-selector-param=\"#{param}\" data-selector-value=\"#{value}\" #{'data-selector-default="true"' if default}>#{label}</a>".html_safe

end

def additional_info_value(f)
dict = f.object.additional_info
(dict && !dict.empty?) ? dict.to_yaml.gsub("---\n", "") : ""
Expand Down
34 changes: 34 additions & 0 deletions app/models/concerns/follower.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,39 @@ def unfollow(obj)
def follow?(obj)
followings.where(followable: obj).exists?
end

def following_activities
activities = PublicActivity::Activity.arel_table
followings = Following.arel_table
sql = activities.join(followings).on(
# we want activities related to objetcs followed by this user
# AND activities owned by users followed by this user
followings[:followable_type].in([activities[:trackable_type], activities[:owner_type]])
).where(
# Activities from objects followed by this user
Arel::Nodes::Grouping.new(
activities[:trackable_id].eq(followings[:followable_id]).and(
activities[:trackable_type].eq(followings[:followable_type])
)
).or(
# Activities owned by users followed by this user
Arel::Nodes::Grouping.new(
activities[:owner_id].eq(followings[:followable_id]).and(
followings[:followable_type].eq(self.class.name)
)
)
).and(
# Only followed by this user
followings[:follower_id].eq(self.id)
).and(
# But remove activities owned by this user itself
activities[:owner_type].eq(self.class.name).and(
activities[:owner_id].not_eq(self.id))
)
).project('activities.id')
# Convert to ActiveRecord Relation
PublicActivity::Activity.includes(:trackable).where(
activities[:id].in(sql)).order("activities.created_at desc")
end
end
end
2 changes: 1 addition & 1 deletion app/models/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def geojson_properties
end

def activities_performed
PublicActivity::Activity.where(owner: self).includes(:trackable, :owner).order('created_at desc')
PublicActivity::Activity.where(owner: self).includes(:trackable).order('created_at desc')
end

def notifications
Expand Down
Loading

0 comments on commit a4bf1c6

Please sign in to comment.