tent-status 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +21 -0
- data/.kick +8 -0
- data/Gemfile +12 -0
- data/Gemfile.lock +232 -0
- data/LICENSE.txt +22 -0
- data/Procfile +1 -0
- data/README.md +14 -0
- data/Rakefile +43 -0
- data/assets/images/.gitkeep +0 -0
- data/assets/images/chosen-sprite.png +0 -0
- data/assets/images/glyphicons-halflings-white.png +0 -0
- data/assets/images/glyphicons-halflings.png +0 -0
- data/assets/javascripts/.gitkeep +0 -0
- data/assets/javascripts/application.js.coffee +122 -0
- data/assets/javascripts/backbone.js +1443 -0
- data/assets/javascripts/backbone_sync.js.coffee +60 -0
- data/assets/javascripts/boot.js.coffee +3 -0
- data/assets/javascripts/chosen.jquery.js +1129 -0
- data/assets/javascripts/collections/.gitkeep +0 -0
- data/assets/javascripts/collections/followers.js.coffee +5 -0
- data/assets/javascripts/collections/followings.js.coffee +5 -0
- data/assets/javascripts/collections/groups.js.coffee +5 -0
- data/assets/javascripts/collections/posts.js.coffee +5 -0
- data/assets/javascripts/fetch_pool.js.coffee +25 -0
- data/assets/javascripts/helpers/.gitkeep +0 -0
- data/assets/javascripts/helpers/formatting.js.coffee +17 -0
- data/assets/javascripts/hogan.js +706 -0
- data/assets/javascripts/http.js.coffee +18 -0
- data/assets/javascripts/jquery.js +9301 -0
- data/assets/javascripts/models/.gitkeep +0 -0
- data/assets/javascripts/models/follower.js.coffee +27 -0
- data/assets/javascripts/models/following.js.coffee +27 -0
- data/assets/javascripts/models/group.js.coffee +4 -0
- data/assets/javascripts/models/post.js.coffee +32 -0
- data/assets/javascripts/models/profile.js.coffee +30 -0
- data/assets/javascripts/moment.js +1106 -0
- data/assets/javascripts/paginator.js.coffee +67 -0
- data/assets/javascripts/router.js.coffee +71 -0
- data/assets/javascripts/routers/.gitkeep +0 -0
- data/assets/javascripts/routers/followers.js.coffee +14 -0
- data/assets/javascripts/routers/followings.js.coffee +14 -0
- data/assets/javascripts/routers/posts.js.coffee +98 -0
- data/assets/javascripts/templates/.gitkeep +0 -0
- data/assets/javascripts/templates/_follower.js.mustache.slim +17 -0
- data/assets/javascripts/templates/_following.js.mustache.slim +17 -0
- data/assets/javascripts/templates/_new_post_form.js.mustache.slim +10 -0
- data/assets/javascripts/templates/_post.js.mustache.slim +10 -0
- data/assets/javascripts/templates/_post_inner.js.mustache.slim +71 -0
- data/assets/javascripts/templates/_profile_stats.js.mustache.slim +11 -0
- data/assets/javascripts/templates/_reply_form.js.mustache.slim +13 -0
- data/assets/javascripts/templates/conversation.js.mustache.slim +13 -0
- data/assets/javascripts/templates/followers.js.mustache.slim +19 -0
- data/assets/javascripts/templates/followings.js.mustache.slim +22 -0
- data/assets/javascripts/templates/posts.js.mustache.slim +25 -0
- data/assets/javascripts/templates/profile.js.mustache.slim +39 -0
- data/assets/javascripts/underscore.js +1059 -0
- data/assets/javascripts/view.js.coffee +140 -0
- data/assets/javascripts/views/.gitkeep +0 -0
- data/assets/javascripts/views/container.js.coffee +6 -0
- data/assets/javascripts/views/expanding_textarea.js.coffee +14 -0
- data/assets/javascripts/views/fetch_posts_pool.js.coffee +61 -0
- data/assets/javascripts/views/follower_groups_form.js.coffee +26 -0
- data/assets/javascripts/views/followers.js.coffee +28 -0
- data/assets/javascripts/views/following_groups_form.js.coffee +25 -0
- data/assets/javascripts/views/followings.js.coffee +27 -0
- data/assets/javascripts/views/new_following_form.js.coffee +15 -0
- data/assets/javascripts/views/new_post_form.js.coffee +178 -0
- data/assets/javascripts/views/post.js.coffee +139 -0
- data/assets/javascripts/views/posts.js.coffee +55 -0
- data/assets/javascripts/views/posts/conversation.js.coffee +18 -0
- data/assets/javascripts/views/profile.js.coffee +29 -0
- data/assets/javascripts/views/profile_follow_button.js.coffee +29 -0
- data/assets/javascripts/views/profile_stats.js.coffee +38 -0
- data/assets/javascripts/views/remove_follower_btn.js.coffee +18 -0
- data/assets/javascripts/views/reply_post_form.js.coffee +30 -0
- data/assets/javascripts/views/unfollow_btn.js.coffee +18 -0
- data/assets/stylesheets/.gitkeep +0 -0
- data/assets/stylesheets/application.css.sass +117 -0
- data/assets/stylesheets/bootstrap-responsive.css +1040 -0
- data/assets/stylesheets/bootstrap.css.erb +5624 -0
- data/assets/stylesheets/chosen.css.erb +397 -0
- data/config.ru +14 -0
- data/config/asset_sync.rb +12 -0
- data/config/evergreen.rb +16 -0
- data/lib/tent-status.rb +6 -0
- data/lib/tent-status/app.rb +263 -0
- data/lib/tent-status/models/user.rb +39 -0
- data/lib/tent-status/sprockets/environment.rb +25 -0
- data/lib/tent-status/sprockets/helpers.rb +5 -0
- data/lib/tent-status/views/application.slim +69 -0
- data/lib/tent-status/views/auth.slim +8 -0
- data/tent-status.gemspec +34 -0
- metadata +415 -0
@@ -0,0 +1,67 @@
|
|
1
|
+
class TentStatus.Paginator
|
2
|
+
sinceId: null
|
3
|
+
limit: TentStatus.PER_PAGE || 50
|
4
|
+
onLastPage: false
|
5
|
+
isPaginator: true
|
6
|
+
|
7
|
+
constructor: (@collection, @options = {}) ->
|
8
|
+
@url = @options.url if @options.url
|
9
|
+
@url ||= @collection.url?()
|
10
|
+
@url ||= @collection.url
|
11
|
+
|
12
|
+
fetch: (options = {}) =>
|
13
|
+
sinceId = @sinceId
|
14
|
+
limit = @limit
|
15
|
+
|
16
|
+
@trigger 'fetch:start'
|
17
|
+
|
18
|
+
loadedCount = @collection.length
|
19
|
+
expectedCount = loadedCount + limit
|
20
|
+
|
21
|
+
_options = {
|
22
|
+
url: @urlForOffsetAndLimit(sinceId, limit)
|
23
|
+
add: true
|
24
|
+
success: (items) =>
|
25
|
+
if (loadedCount == @collection.length) or (@collection.length < expectedCount)
|
26
|
+
@onLastPage = true
|
27
|
+
@sinceId = items.last()?.get('id')
|
28
|
+
@options.success?()
|
29
|
+
@trigger 'fetch:success'
|
30
|
+
error: =>
|
31
|
+
@trigger 'fetch:error'
|
32
|
+
}
|
33
|
+
options = _.extend _options, options
|
34
|
+
|
35
|
+
@collection.fetch(options)
|
36
|
+
|
37
|
+
urlForOffsetAndLimit: (sinceId, limit) =>
|
38
|
+
separator = if @url.indexOf("?") != -1 then "&" else "?"
|
39
|
+
@url + separator + @serializeParams(@paramsForOffsetAndLimit sinceId, limit)
|
40
|
+
|
41
|
+
serializeParams: (params = {}) =>
|
42
|
+
res = []
|
43
|
+
for k, v of params
|
44
|
+
continue if @url.match("#{k}=")
|
45
|
+
res.push "#{k}=#{v}"
|
46
|
+
res.join("&")
|
47
|
+
|
48
|
+
paramsForOffsetAndLimit: (sinceId, limit) =>
|
49
|
+
params = { limit: limit }
|
50
|
+
params.before_id = sinceId if sinceId
|
51
|
+
params
|
52
|
+
|
53
|
+
nextPage: =>
|
54
|
+
@fetch()
|
55
|
+
|
56
|
+
toJSON: => @collection.toJSON()
|
57
|
+
toArray: => @collection.toArray()
|
58
|
+
find: => @collection.find(arguments...)
|
59
|
+
filter: => @collection.filter(arguments...)
|
60
|
+
sortBy: => @collection.sortBy(arguments...)
|
61
|
+
get: => @collection.get(arguments...)
|
62
|
+
unshift: => @collection.unshift(arguments...)
|
63
|
+
push: => @collection.push(arguments...)
|
64
|
+
first: => @collection.first(arguments...)
|
65
|
+
last: => @collection.last(arguments...)
|
66
|
+
|
67
|
+
_.extend TentStatus.Paginator::, Backbone.Events
|
@@ -0,0 +1,71 @@
|
|
1
|
+
# All routers should extend TentStatus.Router
|
2
|
+
# Any abstractions should go in here
|
3
|
+
class TentStatus.Router extends Backbone.Router
|
4
|
+
keyForAction: (actionName) =>
|
5
|
+
"#{@routerKey}:#{actionName}"
|
6
|
+
|
7
|
+
setCurrentAction: (actionName, actionFn) =>
|
8
|
+
if TentStatus.freezeRouter
|
9
|
+
TentStatus.on 'router:unfreeze', (shouldPlay) => @setCurrentAction(actionName, actionFn) if shouldPlay
|
10
|
+
|
11
|
+
key = @keyForAction(actionName)
|
12
|
+
|
13
|
+
@_dataFetches ||= {}
|
14
|
+
@_dataFetches[actionName] = 0
|
15
|
+
|
16
|
+
@view?.empty()
|
17
|
+
|
18
|
+
@currentActionName = actionName
|
19
|
+
|
20
|
+
window.scrollTo window.scrollX, 0
|
21
|
+
|
22
|
+
TentStatus.setPageTitle? key
|
23
|
+
TentStatus.setCurrentRoute? @, actionName
|
24
|
+
|
25
|
+
actionFn()
|
26
|
+
|
27
|
+
isCurrentAction: (actionName) =>
|
28
|
+
return true # currentRoute not currently setup, TODO set this up
|
29
|
+
TentStatus.currentRoute?.key == @keyForAction(actionName)
|
30
|
+
|
31
|
+
fetchData: (dataKey, dataFn) =>
|
32
|
+
actionName = @currentActionName
|
33
|
+
|
34
|
+
if dataFn.length == 0
|
35
|
+
@_fetchData(dataKey, dataFn(), actionName)
|
36
|
+
else
|
37
|
+
dataFn (res) => @_fetchData(dataKey, res, actionName)
|
38
|
+
|
39
|
+
_fetchData: (dataKey, res, actionName) =>
|
40
|
+
loaded = =>
|
41
|
+
@view?.set dataKey, res[dataKey]
|
42
|
+
|
43
|
+
# yield for other fetchData calls to start
|
44
|
+
setTimeout (=> @fetchSuccess actionName), 0
|
45
|
+
|
46
|
+
if res.loaded is true
|
47
|
+
@fetchStart actionName
|
48
|
+
loaded()
|
49
|
+
else
|
50
|
+
res[dataKey].on 'fetch:start', (=> @fetchStart actionName)
|
51
|
+
res[dataKey].on 'fetch:success', loaded
|
52
|
+
if res[dataKey].isPaginator is true
|
53
|
+
# TentStatus.Paginator triggers 'fetch:start' and 'fetch:success' events
|
54
|
+
res[dataKey].fetch()
|
55
|
+
else
|
56
|
+
res[dataKey].trigger 'fetch:start'
|
57
|
+
res[dataKey].fetch success: (=> res[dataKey].trigger 'fetch:success')
|
58
|
+
|
59
|
+
fetchStart: (actionName) =>
|
60
|
+
return unless @isCurrentAction(actionName)
|
61
|
+
@_dataFetches[actionName]++
|
62
|
+
TentStatus.Views.loading?.show()
|
63
|
+
|
64
|
+
fetchSuccess: (actionName) =>
|
65
|
+
return unless @isCurrentAction(actionName)
|
66
|
+
@_dataFetches[actionName]-- unless @_dataFetches[actionName] == 0
|
67
|
+
if @_dataFetches[actionName] == 0
|
68
|
+
@view?.once 'ready', =>
|
69
|
+
TentStatus.Views.loading?.hide()
|
70
|
+
@view?.render()
|
71
|
+
|
File without changes
|
@@ -0,0 +1,14 @@
|
|
1
|
+
TentStatus.Routers.followers = new class Followers extends TentStatus.Router
|
2
|
+
routerKey: 'followers'
|
3
|
+
|
4
|
+
routes:
|
5
|
+
"followers" : "index"
|
6
|
+
|
7
|
+
index: =>
|
8
|
+
return if TentStatus.guest_authenticated || !TentStatus.authenticated
|
9
|
+
@view = new TentStatus.Views.Followers
|
10
|
+
@setCurrentAction 'index', =>
|
11
|
+
@fetchData 'followers', =>
|
12
|
+
{ followers: new TentStatus.Paginator( TentStatus.Collections.followers ), loaded: false }
|
13
|
+
@fetchData 'groups', =>
|
14
|
+
{ groups: new TentStatus.Paginator( TentStatus.Collections.groups ), loaded: false }
|
@@ -0,0 +1,14 @@
|
|
1
|
+
TentStatus.Routers.followings = new class FollowingsRouter extends TentStatus.Router
|
2
|
+
routerKey: 'followings'
|
3
|
+
|
4
|
+
routes:
|
5
|
+
"followings" : "index"
|
6
|
+
|
7
|
+
index: =>
|
8
|
+
return if TentStatus.guest_authenticated || !TentStatus.authenticated
|
9
|
+
@view = new TentStatus.Views.Followings
|
10
|
+
@setCurrentAction 'index', =>
|
11
|
+
@fetchData 'groups', =>
|
12
|
+
{ groups: new TentStatus.Paginator( TentStatus.Collections.groups ), loaded: false }
|
13
|
+
@fetchData 'followings', =>
|
14
|
+
{ followings: new TentStatus.Paginator( TentStatus.Collections.followings ), loaded: false }
|
@@ -0,0 +1,98 @@
|
|
1
|
+
TentStatus.Routers.posts = new class PostsRouter extends TentStatus.Router
|
2
|
+
routerKey: 'posts'
|
3
|
+
|
4
|
+
routes:
|
5
|
+
"" : "root"
|
6
|
+
"profile" : "myProfile"
|
7
|
+
"posts" : "index"
|
8
|
+
"entities/:entity" : "profile"
|
9
|
+
"entities/:entity/:post_id" : "conversation"
|
10
|
+
|
11
|
+
index: =>
|
12
|
+
unless TentStatus.current_entity == TentStatus.domain_entity
|
13
|
+
@profile(encodeURIComponent(TentStatus.domain_entity))
|
14
|
+
return
|
15
|
+
@view = new TentStatus.Views.Posts
|
16
|
+
window.view = @view
|
17
|
+
@setCurrentAction 'index', =>
|
18
|
+
@fetchData 'posts', =>
|
19
|
+
{ posts: new TentStatus.Paginator( TentStatus.Collections.posts ), loaded: false }
|
20
|
+
@fetchData 'followers', =>
|
21
|
+
{ followers: new TentStatus.Paginator( TentStatus.Collections.followers ), loaded: false }
|
22
|
+
@fetchData 'followings', =>
|
23
|
+
{ followings: new TentStatus.Paginator( TentStatus.Collections.followings ), loaded: false }
|
24
|
+
@fetchData 'profile', =>
|
25
|
+
{ profile: TentStatus.Models.profile, loaded: false }
|
26
|
+
|
27
|
+
root: => @index(arguments...)
|
28
|
+
|
29
|
+
conversation: (entity, post_id) =>
|
30
|
+
@view = new TentStatus.Views.Conversation
|
31
|
+
@setCurrentAction 'conversation', =>
|
32
|
+
@fetchData 'post', =>
|
33
|
+
_post = new TentStatus.Models.Post { id: post_id }
|
34
|
+
{ post: _post, loaded: false }
|
35
|
+
|
36
|
+
@fetchData 'posts', =>
|
37
|
+
query_string = "mentioned_entity=#{entity}&mentioned_post=#{post_id}"
|
38
|
+
options =
|
39
|
+
url: "#{(new TentStatus.Collections.Posts).url}?#{query_string}"
|
40
|
+
|
41
|
+
_posts = new TentStatus.Paginator( new TentStatus.Collections.Posts, options )
|
42
|
+
{ posts: _posts, loaded: false }
|
43
|
+
|
44
|
+
@fetchData 'followers', =>
|
45
|
+
{ followers: new TentStatus.Paginator( TentStatus.Collections.followers ), loaded: false }
|
46
|
+
@fetchData 'followings', =>
|
47
|
+
{ followings: new TentStatus.Paginator( TentStatus.Collections.followings ), loaded: false }
|
48
|
+
@fetchData 'profile', =>
|
49
|
+
{ profile: TentStatus.Models.profile, loaded: false }
|
50
|
+
|
51
|
+
myProfile: =>
|
52
|
+
@profile(TentStatus.current_entity)
|
53
|
+
|
54
|
+
profile: (entity) =>
|
55
|
+
@view = new TentStatus.Views.Profile
|
56
|
+
@setCurrentAction 'profile', =>
|
57
|
+
@fetchData 'currentProfile', (callback) =>
|
58
|
+
_loadedCalled = 0
|
59
|
+
_loaded = (data) =>
|
60
|
+
return unless data
|
61
|
+
return if _loadedCalled
|
62
|
+
_loadedCalled = true
|
63
|
+
|
64
|
+
_profile = new TentStatus.Models.Profile data
|
65
|
+
callback({ currentProfile: _profile, loaded: true })
|
66
|
+
|
67
|
+
_following = new TentStatus.Models.Following entity: decodeURIComponent(entity)
|
68
|
+
_following.fetch
|
69
|
+
url: "#{TentStatus.api_root}/followings?entity=#{entity}"
|
70
|
+
success: =>
|
71
|
+
return _loaded(false) unless _profile = _following.toJSON()[0]?.profile
|
72
|
+
_loaded _.extend({follow_type: 'followings'}, _profile)
|
73
|
+
|
74
|
+
_follower = new TentStatus.Models.Follower entity: decodeURIComponent(entity)
|
75
|
+
_follower.fetch
|
76
|
+
url: "#{TentStatus.api_root}/followers?entity=#{entity}"
|
77
|
+
success: =>
|
78
|
+
return _loaded(false) unless _profile = _follower.toJSON()[0]?.profile
|
79
|
+
_loaded _.extend({follow_type: 'followers'}, _profile)
|
80
|
+
|
81
|
+
@fetchData 'profile', (profileCallback) =>
|
82
|
+
TentStatus.Models.profile.fetch
|
83
|
+
success: (profile) =>
|
84
|
+
if profile.entity() == decodeURIComponent(entity)
|
85
|
+
_loadedCalled = true
|
86
|
+
callback({ currentProfile: profile, loaded: true })
|
87
|
+
profileCallback({ profile: TentStatus.Models.profile, loaded: true })
|
88
|
+
|
89
|
+
@fetchData 'posts', (callback) =>
|
90
|
+
options = { url: "#{TentStatus.api_root}/posts?entity=#{entity}" }
|
91
|
+
_posts = new TentStatus.Paginator( new TentStatus.Collections.Posts, options )
|
92
|
+
callback({ posts: _posts, loaded: false })
|
93
|
+
|
94
|
+
@fetchData 'followers', =>
|
95
|
+
{ followers: new TentStatus.Paginator( TentStatus.Collections.followers ), loaded: false }
|
96
|
+
@fetchData 'followings', =>
|
97
|
+
{ followings: new TentStatus.Paginator( TentStatus.Collections.followings ), loaded: false }
|
98
|
+
|
File without changes
|
@@ -0,0 +1,17 @@
|
|
1
|
+
tr
|
2
|
+
td
|
3
|
+
=="{{#avatar}}"
|
4
|
+
a href='{{entity}}'
|
5
|
+
img.img-rounded src='{{avatar}}' style='height:50px;width:50px;margin-right:4px;'
|
6
|
+
=="{{/avatar}}"
|
7
|
+
a href='{{entity}}'
|
8
|
+
=="{{name}}"
|
9
|
+
td =="{{entity}}"
|
10
|
+
td
|
11
|
+
form data-view='FollowerGroupsForm' data-follower-id='{{id}}' method='POST'
|
12
|
+
select multiple=true name='groups' data-placeholder='Select some groups'
|
13
|
+
=="{{#groups}}"
|
14
|
+
|<option value='{{id}}' {{#selected}}selected='selected'{{/selected}}>{{name}}</option>
|
15
|
+
=="{{/groups}}"
|
16
|
+
td
|
17
|
+
.btn.btn-danger data-view='RemoveFollowerBtn' data-id='{{id}}' data-confirm='Remove {{name}}?' Remove
|
@@ -0,0 +1,17 @@
|
|
1
|
+
tr
|
2
|
+
td
|
3
|
+
=="{{#avatar}}"
|
4
|
+
a href='{{entity}}'
|
5
|
+
img.img-rounded src='{{avatar}}' style='height:50px;width:50px;margin-right:4px;'
|
6
|
+
=="{{/avatar}}"
|
7
|
+
a href='{{entity}}'
|
8
|
+
=="{{name}}"
|
9
|
+
td =="{{entity}}"
|
10
|
+
td
|
11
|
+
form data-view='FollowingGroupsForm' data-following-id='{{id}}' method='POST'
|
12
|
+
select multiple=true name='groups' data-placeholder='Select some groups'
|
13
|
+
=="{{#groups}}"
|
14
|
+
|<option value='{{id}}' {{#selected}}selected='selected'{{/selected}}>{{name}}</option>
|
15
|
+
=="{{/groups}}"
|
16
|
+
td
|
17
|
+
.btn.btn-danger data-view='UnfollowBtn' data-id='{{id}}' data-confirm='Unfollow {{name}}?' Unfollow
|
@@ -0,0 +1,10 @@
|
|
1
|
+
| {{#authenticated}}
|
2
|
+
form.form-horizontal data-view='NewPostForm' method='POST'
|
3
|
+
.span6
|
4
|
+
.alert.alert-error
|
5
|
+
|
6
|
+
textarea.span6 name='text' placeholder="What's on your mind?" rows='3'
|
7
|
+
span.char-limit 140
|
8
|
+
|
9
|
+
input.btn.btn-success.pull-right type='submit' value='Post'
|
10
|
+
| {{/authenticated}}
|
@@ -0,0 +1,10 @@
|
|
1
|
+
| {{#isValid}}
|
2
|
+
| {{^isRepost}}
|
3
|
+
li.post.clearfix data-id='{{id}}' data-parent-id='{{parent.id}}' data-post-found='{{#parent}}yes{{/parent}}'
|
4
|
+
| {{> _post_inner}}
|
5
|
+
| {{/isRepost}}
|
6
|
+
| {{#isRepost}}
|
7
|
+
li.post.clearfix data-parent-id='{{id}}' data-post-found='no'
|
8
|
+
| {{> _post_inner}}
|
9
|
+
| {{/isRepost}}
|
10
|
+
| {{/isValid}}
|
@@ -0,0 +1,71 @@
|
|
1
|
+
.row
|
2
|
+
.span1
|
3
|
+
aFollowing href='{{entity}}'
|
4
|
+
img.img-rounded.pull-left.avatar src='{{avatar}}'
|
5
|
+
|
6
|
+
.span3.no-offset
|
7
|
+
h5 style='margin: 0px;'
|
8
|
+
a href='{{entity}}' {{name}} {{#hasName}}<small>{{formatted.entity}}</small>{{/hasName}}
|
9
|
+
|
10
|
+
.pull-right
|
11
|
+
a href='{{url}}' class='{{#parent}}gray{{/parent}}' title='{{formatted.full_published_at}}' {{formatted.published_at}}
|
12
|
+
|
13
|
+
| {{#inReplyTo}}
|
14
|
+
| {{#authenticated}}
|
15
|
+
.span5
|
16
|
+
a href='{{url}}'
|
17
|
+
small in reply to {{name}}
|
18
|
+
| {{/authenticated}}
|
19
|
+
| {{/inReplyTo}}
|
20
|
+
|
21
|
+
| {{^repost}}
|
22
|
+
| {{#parent}}
|
23
|
+
p.span5.no-offset
|
24
|
+
| {{content.text}}
|
25
|
+
| {{/parent}}
|
26
|
+
| {{^parent}}
|
27
|
+
p.span6.no-offset
|
28
|
+
| {{content.text}}
|
29
|
+
| {{/parent}}
|
30
|
+
| {{/repost}}
|
31
|
+
|
32
|
+
| {{#repost}}
|
33
|
+
| {{#authenticated}}
|
34
|
+
.span7.repost.no-offset style='width:560px;'
|
35
|
+
| {{> _post_inner}}
|
36
|
+
.span6.offset1
|
37
|
+
| Reposted by {{parent.name}}
|
38
|
+
small.pull-right via {{app.name}}
|
39
|
+
| {{/authenticated}}
|
40
|
+
| {{/repost}}
|
41
|
+
|
42
|
+
| {{#authenticated}}
|
43
|
+
.row.offset0-6.showOnHover.navigation
|
44
|
+
| {{^repost}}
|
45
|
+
| {{^currentUserOwnsPost}}
|
46
|
+
a.reply href='#' Reply
|
47
|
+
a.repost data-confirm='Repost {{nmae}}?' href='#' Repost
|
48
|
+
| {{/currentUserOwnsPost}}
|
49
|
+
| {{/repost}}
|
50
|
+
| {{#currentUserOwnsPost}}
|
51
|
+
a.delete data-confirm='Delete Post?' href='#' Delete
|
52
|
+
| {{/currentUserOwnsPost}}
|
53
|
+
| {{^repost}}
|
54
|
+
| {{^parent}}
|
55
|
+
small.pull-right via {{app.name}}
|
56
|
+
| {{/parent}}
|
57
|
+
| {{/repost}}
|
58
|
+
| {{/authenticated}}
|
59
|
+
|
60
|
+
| {{^repost}}
|
61
|
+
| {{#authenticated}}
|
62
|
+
| {{^parent}}
|
63
|
+
.row.offset0-5.reply-container.clearfix
|
64
|
+
| {{> _reply_form}}
|
65
|
+
| {{/parent}}
|
66
|
+
| {{#parent}}
|
67
|
+
.row.reply-container.clearfix
|
68
|
+
| {{> _reply_form}}
|
69
|
+
| {{/parent}}
|
70
|
+
| {{/authenticated}}
|
71
|
+
| {{/repost}}
|
@@ -0,0 +1,13 @@
|
|
1
|
+
| {{#authenticated}}
|
2
|
+
form.form-horizontal data-view='ReplyPostForm' method='POST'
|
3
|
+
input type='hidden' name='mentions_post_id' value='{{id}}'
|
4
|
+
input type='hidden' name='mentions_post_entity' value='{{entity}}'
|
5
|
+
.span7
|
6
|
+
.alert.alert-error
|
7
|
+
|
8
|
+
textarea.span7 name='text' placeholder="What's on your mind?" rows='3' ^{{entity}}
|
9
|
+
.clearfix
|
10
|
+
span.char-limit 140
|
11
|
+
|
12
|
+
input.btn.btn-success.pull-right type='submit' value='Post'
|
13
|
+
| {{/authenticated}}
|