Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-platform
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
edx
edx-platform
Commits
f0737c18
Commit
f0737c18
authored
Aug 23, 2012
by
Tom Giannattasio
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' into feature/tomg/fall-design
parents
32393efe
e0229836
Hide whitespace changes
Inline
Side-by-side
Showing
32 changed files
with
837 additions
and
694 deletions
+837
-694
common/lib/capa/capa/inputtypes.py
+3
-3
common/lib/capa/capa/templates/choicegroup.html
+0
-3
lms/djangoapps/django_comment_client/base/views.py
+20
-10
lms/djangoapps/django_comment_client/forum/views.py
+5
-2
lms/djangoapps/django_comment_client/helpers.py
+10
-16
lms/djangoapps/django_comment_client/mustache_helpers.py
+2
-1
lms/djangoapps/django_comment_client/settings.py
+10
-0
lms/djangoapps/django_comment_client/utils.py
+19
-0
lms/envs/aws.py
+1
-1
lms/envs/common.py
+4
-0
lms/envs/dev.py
+2
-0
lms/lib/comment_client/settings.py
+4
-1
lms/static/coffee/src/discussion/content.coffee
+417
-396
lms/static/coffee/src/discussion/discussion.coffee
+174
-163
lms/static/coffee/src/discussion/discussion_module.coffee
+33
-31
lms/static/coffee/src/discussion/main.coffee
+7
-1
lms/static/coffee/src/discussion/user_profile.coffee
+28
-33
lms/static/coffee/src/discussion/utils.coffee
+15
-1
lms/static/images/discussion/loading.gif
+0
-0
lms/static/sass/_discussion.scss
+7
-3
lms/static/sass/course.scss
+6
-0
lms/static/sass/course/courseware/courses/_cs188.scss
+32
-0
lms/templates/courseware/courseware.html
+1
-0
lms/templates/discussion/_content_renderer.html
+7
-7
lms/templates/discussion/_similar_posts.html
+9
-0
lms/templates/discussion/_user_active_threads.html
+4
-4
lms/templates/discussion/_user_profile.html
+3
-3
lms/templates/discussion/index.html
+2
-2
lms/templates/discussion/mustache/_content.mustache
+4
-2
lms/templates/discussion/mustache/_new_post.mustache
+1
-5
lms/templates/discussion/single_thread.html
+2
-2
lms/templates/discussion/user_profile.html
+5
-4
No files found.
common/lib/capa/capa/inputtypes.py
View file @
f0737c18
...
@@ -185,7 +185,7 @@ def choicegroup(element, value, status, render_template, msg=''):
...
@@ -185,7 +185,7 @@ def choicegroup(element, value, status, render_template, msg=''):
if
choice
.
text
is
not
None
:
if
choice
.
text
is
not
None
:
ctext
+=
choice
.
text
# TODO: fix order?
ctext
+=
choice
.
text
# TODO: fix order?
choices
.
append
((
choice
.
get
(
"name"
),
ctext
))
choices
.
append
((
choice
.
get
(
"name"
),
ctext
))
context
=
{
'id'
:
eid
,
'value'
:
value
,
'state'
:
status
,
'input_type'
:
type
,
'choices'
:
choices
,
'
inline'
:
True
,
'
name_array_suffix'
:
''
}
context
=
{
'id'
:
eid
,
'value'
:
value
,
'state'
:
status
,
'input_type'
:
type
,
'choices'
:
choices
,
'name_array_suffix'
:
''
}
html
=
render_template
(
"choicegroup.html"
,
context
)
html
=
render_template
(
"choicegroup.html"
,
context
)
return
etree
.
XML
(
html
)
return
etree
.
XML
(
html
)
...
@@ -226,7 +226,7 @@ def radiogroup(element, value, status, render_template, msg=''):
...
@@ -226,7 +226,7 @@ def radiogroup(element, value, status, render_template, msg=''):
choices
=
extract_choices
(
element
)
choices
=
extract_choices
(
element
)
context
=
{
'id'
:
eid
,
'value'
:
value
,
'state'
:
status
,
'input_type'
:
'radio'
,
'choices'
:
choices
,
'
inline'
:
False
,
'
name_array_suffix'
:
'[]'
}
context
=
{
'id'
:
eid
,
'value'
:
value
,
'state'
:
status
,
'input_type'
:
'radio'
,
'choices'
:
choices
,
'name_array_suffix'
:
'[]'
}
html
=
render_template
(
"choicegroup.html"
,
context
)
html
=
render_template
(
"choicegroup.html"
,
context
)
return
etree
.
XML
(
html
)
return
etree
.
XML
(
html
)
...
@@ -244,7 +244,7 @@ def checkboxgroup(element, value, status, render_template, msg=''):
...
@@ -244,7 +244,7 @@ def checkboxgroup(element, value, status, render_template, msg=''):
choices
=
extract_choices
(
element
)
choices
=
extract_choices
(
element
)
context
=
{
'id'
:
eid
,
'value'
:
value
,
'state'
:
status
,
'input_type'
:
'checkbox'
,
'choices'
:
choices
,
'
inline'
:
False
,
'
name_array_suffix'
:
'[]'
}
context
=
{
'id'
:
eid
,
'value'
:
value
,
'state'
:
status
,
'input_type'
:
'checkbox'
,
'choices'
:
choices
,
'name_array_suffix'
:
'[]'
}
html
=
render_template
(
"choicegroup.html"
,
context
)
html
=
render_template
(
"choicegroup.html"
,
context
)
return
etree
.
XML
(
html
)
return
etree
.
XML
(
html
)
...
...
common/lib/capa/capa/templates/choicegroup.html
View file @
f0737c18
...
@@ -6,9 +6,6 @@
...
@@ -6,9 +6,6 @@
checked=
"true"
checked=
"true"
%
endif
%
endif
/>
${choice_description}
</label>
/>
${choice_description}
</label>
% if not inline:
<br/>
% endif
% endfor
% endfor
<span
id=
"answer_${id}"
></span>
<span
id=
"answer_${id}"
></span>
...
...
lms/djangoapps/django_comment_client/base/views.py
View file @
f0737c18
...
@@ -8,6 +8,8 @@ import functools
...
@@ -8,6 +8,8 @@ import functools
import
comment_client
as
cc
import
comment_client
as
cc
import
django_comment_client.utils
as
utils
import
django_comment_client.utils
as
utils
import
django_comment_client.settings
as
cc_settings
from
django.core
import
exceptions
from
django.core
import
exceptions
from
django.contrib.auth.decorators
import
login_required
from
django.contrib.auth.decorators
import
login_required
...
@@ -15,13 +17,11 @@ from django.views.decorators.http import require_POST, require_GET
...
@@ -15,13 +17,11 @@ from django.views.decorators.http import require_POST, require_GET
from
django.views.decorators
import
csrf
from
django.views.decorators
import
csrf
from
django.core.files.storage
import
get_storage_class
from
django.core.files.storage
import
get_storage_class
from
django.utils.translation
import
ugettext
as
_
from
django.utils.translation
import
ugettext
as
_
from
django.conf
import
settings
from
django.contrib.auth.models
import
User
from
django.contrib.auth.models
import
User
from
mitxmako.shortcuts
import
render_to_response
,
render_to_string
from
mitxmako.shortcuts
import
render_to_response
,
render_to_string
from
courseware.courses
import
get_course_with_access
from
courseware.courses
import
get_course_with_access
from
django_comment_client.utils
import
JsonResponse
,
JsonError
,
extract
from
django_comment_client.utils
import
JsonResponse
,
JsonError
,
extract
from
django_comment_client.permissions
import
check_permissions_by_view
from
django_comment_client.permissions
import
check_permissions_by_view
...
@@ -115,6 +115,9 @@ def _create_comment(request, course_id, thread_id=None, parent_id=None):
...
@@ -115,6 +115,9 @@ def _create_comment(request, course_id, thread_id=None, parent_id=None):
@login_required
@login_required
@permitted
@permitted
def
create_comment
(
request
,
course_id
,
thread_id
):
def
create_comment
(
request
,
course_id
,
thread_id
):
if
cc_settings
.
MAX_COMMENT_DEPTH
is
not
None
:
if
cc_settings
.
MAX_COMMENT_DEPTH
<
0
:
return
JsonError
(
"Comment level too deep"
)
return
_create_comment
(
request
,
course_id
,
thread_id
=
thread_id
)
return
_create_comment
(
request
,
course_id
,
thread_id
=
thread_id
)
@require_POST
@require_POST
...
@@ -159,6 +162,9 @@ def openclose_thread(request, course_id, thread_id):
...
@@ -159,6 +162,9 @@ def openclose_thread(request, course_id, thread_id):
@login_required
@login_required
@permitted
@permitted
def
create_sub_comment
(
request
,
course_id
,
comment_id
):
def
create_sub_comment
(
request
,
course_id
,
comment_id
):
if
cc_settings
.
MAX_COMMENT_DEPTH
is
not
None
:
if
cc_settings
.
MAX_COMMENT_DEPTH
<=
cc
.
Comment
.
find
(
comment_id
)
.
depth
:
return
JsonError
(
"Comment level too deep"
)
return
_create_comment
(
request
,
course_id
,
parent_id
=
comment_id
)
return
_create_comment
(
request
,
course_id
,
parent_id
=
comment_id
)
@require_POST
@require_POST
...
@@ -282,7 +288,7 @@ def update_moderator_status(request, course_id, user_id):
...
@@ -282,7 +288,7 @@ def update_moderator_status(request, course_id, user_id):
'course_id'
:
course_id
,
'course_id'
:
course_id
,
'user'
:
request
.
user
,
'user'
:
request
.
user
,
'django_user'
:
user
,
'django_user'
:
user
,
'
discussion
_user'
:
discussion_user
.
to_dict
(),
'
profiled
_user'
:
discussion_user
.
to_dict
(),
}
}
return
JsonResponse
({
return
JsonResponse
({
'html'
:
render_to_string
(
'discussion/ajax_user_profile.html'
,
context
)
'html'
:
render_to_string
(
'discussion/ajax_user_profile.html'
,
context
)
...
@@ -298,10 +304,13 @@ def search_similar_threads(request, course_id, commentable_id):
...
@@ -298,10 +304,13 @@ def search_similar_threads(request, course_id, commentable_id):
'text'
:
text
,
'text'
:
text
,
'commentable_id'
:
commentable_id
,
'commentable_id'
:
commentable_id
,
}
}
result
=
cc
.
search_similar_threads
(
course_id
,
recursive
=
False
,
query_params
=
query_params
)
threads
=
cc
.
search_similar_threads
(
course_id
,
recursive
=
False
,
query_params
=
query_params
)
return
JsonResponse
(
result
)
else
:
else
:
return
JsonResponse
([])
theads
=
[]
context
=
{
'threads'
:
map
(
utils
.
extend_content
,
threads
)
}
return
JsonResponse
({
'html'
:
render_to_string
(
'discussion/_similar_posts.html'
,
context
)
})
@require_GET
@require_GET
def
tags_autocomplete
(
request
,
course_id
):
def
tags_autocomplete
(
request
,
course_id
):
...
@@ -334,8 +343,8 @@ def upload(request, course_id):#ajax upload file to a question or answer
...
@@ -334,8 +343,8 @@ def upload(request, course_id):#ajax upload file to a question or answer
# check file type
# check file type
f
=
request
.
FILES
[
'file-upload'
]
f
=
request
.
FILES
[
'file-upload'
]
file_extension
=
os
.
path
.
splitext
(
f
.
name
)[
1
]
.
lower
()
file_extension
=
os
.
path
.
splitext
(
f
.
name
)[
1
]
.
lower
()
if
not
file_extension
in
settings
.
DISCUSSION_
ALLOWED_UPLOAD_FILE_TYPES
:
if
not
file_extension
in
cc_settings
.
ALLOWED_UPLOAD_FILE_TYPES
:
file_types
=
"', '"
.
join
(
settings
.
DISCUSSION_
ALLOWED_UPLOAD_FILE_TYPES
)
file_types
=
"', '"
.
join
(
cc_settings
.
ALLOWED_UPLOAD_FILE_TYPES
)
msg
=
_
(
"allowed file types are '
%(file_types)
s'"
)
%
\
msg
=
_
(
"allowed file types are '
%(file_types)
s'"
)
%
\
{
'file_types'
:
file_types
}
{
'file_types'
:
file_types
}
raise
exceptions
.
PermissionDenied
(
msg
)
raise
exceptions
.
PermissionDenied
(
msg
)
...
@@ -354,15 +363,16 @@ def upload(request, course_id):#ajax upload file to a question or answer
...
@@ -354,15 +363,16 @@ def upload(request, course_id):#ajax upload file to a question or answer
# check file size
# check file size
# byte
# byte
size
=
file_storage
.
size
(
new_file_name
)
size
=
file_storage
.
size
(
new_file_name
)
if
size
>
settings
.
ASKBOT_
MAX_UPLOAD_FILE_SIZE
:
if
size
>
cc_settings
.
MAX_UPLOAD_FILE_SIZE
:
file_storage
.
delete
(
new_file_name
)
file_storage
.
delete
(
new_file_name
)
msg
=
_
(
"maximum upload file size is
%(file_size)
sK"
)
%
\
msg
=
_
(
"maximum upload file size is
%(file_size)
sK"
)
%
\
{
'file_size'
:
settings
.
ASKBOT_
MAX_UPLOAD_FILE_SIZE
}
{
'file_size'
:
cc_settings
.
MAX_UPLOAD_FILE_SIZE
}
raise
exceptions
.
PermissionDenied
(
msg
)
raise
exceptions
.
PermissionDenied
(
msg
)
except
exceptions
.
PermissionDenied
,
e
:
except
exceptions
.
PermissionDenied
,
e
:
error
=
unicode
(
e
)
error
=
unicode
(
e
)
except
Exception
,
e
:
except
Exception
,
e
:
print
e
logging
.
critical
(
unicode
(
e
))
logging
.
critical
(
unicode
(
e
))
error
=
_
(
'Error uploading file. Please contact the site administrator. Thank you.'
)
error
=
_
(
'Error uploading file. Please contact the site administrator. Thank you.'
)
...
...
lms/djangoapps/django_comment_client/forum/views.py
View file @
f0737c18
...
@@ -83,7 +83,7 @@ def render_discussion(request, course_id, threads, *args, **kwargs):
...
@@ -83,7 +83,7 @@ def render_discussion(request, course_id, threads, *args, **kwargs):
'base_url'
:
base_url
,
'base_url'
:
base_url
,
'query_params'
:
strip_blank
(
strip_none
(
extract
(
query_params
,
[
'page'
,
'sort_key'
,
'sort_order'
,
'tags'
,
'text'
]))),
'query_params'
:
strip_blank
(
strip_none
(
extract
(
query_params
,
[
'page'
,
'sort_key'
,
'sort_order'
,
'tags'
,
'text'
]))),
'annotated_content_info'
:
json
.
dumps
(
annotated_content_info
),
'annotated_content_info'
:
json
.
dumps
(
annotated_content_info
),
'discussion_data'
:
json
.
dumps
({
discussion_id
:
threads
}),
'discussion_data'
:
json
.
dumps
({
(
discussion_id
or
user_id
):
threads
})
}
}
context
=
dict
(
context
.
items
()
+
query_params
.
items
())
context
=
dict
(
context
.
items
()
+
query_params
.
items
())
return
render_to_string
(
template
,
context
)
return
render_to_string
(
template
,
context
)
...
@@ -250,7 +250,10 @@ def user_profile(request, course_id, user_id):
...
@@ -250,7 +250,10 @@ def user_profile(request, course_id, user_id):
content
=
render_user_discussion
(
request
,
course_id
,
threads
,
user_id
=
user_id
,
query_params
=
query_params
)
content
=
render_user_discussion
(
request
,
course_id
,
threads
,
user_id
=
user_id
,
query_params
=
query_params
)
if
request
.
is_ajax
():
if
request
.
is_ajax
():
return
utils
.
HtmlResponse
(
content
)
return
utils
.
JsonResponse
({
'html'
:
content
,
'discussionData'
:
threads
,
})
else
:
else
:
context
=
{
context
=
{
'course'
:
course
,
'course'
:
course
,
...
...
lms/djangoapps/django_comment_client/helpers.py
View file @
f0737c18
...
@@ -6,13 +6,14 @@ from django.core.urlresolvers import reverse
...
@@ -6,13 +6,14 @@ from django.core.urlresolvers import reverse
from
functools
import
partial
from
functools
import
partial
from
utils
import
*
from
utils
import
*
import
django_comment_client.settings
as
cc_settings
import
pystache_custom
as
pystache
import
pystache_custom
as
pystache
import
urllib
import
urllib
import
os
import
os
def
pluralize
(
singular_term
,
count
):
def
pluralize
(
singular_term
,
count
):
if
int
(
count
)
>=
2
:
if
int
(
count
)
>=
2
or
int
(
count
)
==
0
:
return
singular_term
+
's'
return
singular_term
+
's'
return
singular_term
return
singular_term
...
@@ -33,26 +34,19 @@ def include_mustache_templates():
...
@@ -33,26 +34,19 @@ def include_mustache_templates():
file_contents
=
map
(
read_file
,
filter
(
valid_file_name
,
os
.
listdir
(
mustache_dir
)))
file_contents
=
map
(
read_file
,
filter
(
valid_file_name
,
os
.
listdir
(
mustache_dir
)))
return
'
\n
'
.
join
(
map
(
wrap_in_tag
,
map
(
strip_file_name
,
file_contents
)))
return
'
\n
'
.
join
(
map
(
wrap_in_tag
,
map
(
strip_file_name
,
file_contents
)))
def
permalink
(
content
):
if
content
[
'type'
]
==
'thread'
:
return
reverse
(
'django_comment_client.forum.views.single_thread'
,
args
=
[
content
[
'course_id'
],
content
[
'commentable_id'
],
content
[
'id'
]])
else
:
return
reverse
(
'django_comment_client.forum.views.single_thread'
,
args
=
[
content
[
'course_id'
],
content
[
'commentable_id'
],
content
[
'thread_id'
]])
+
'#'
+
content
[
'id'
]
def
render_content
(
content
,
additional_context
=
{}):
def
render_content
(
content
,
additional_context
=
{}):
content_info
=
{
'displayed_title'
:
content
.
get
(
'highlighted_title'
)
or
content
.
get
(
'title'
,
''
),
'displayed_body'
:
content
.
get
(
'highlighted_body'
)
or
content
.
get
(
'body'
,
''
),
'raw_tags'
:
','
.
join
(
content
.
get
(
'tags'
,
[])),
'permalink'
:
permalink
(
content
),
}
context
=
{
context
=
{
'content'
:
merge_dict
(
content
,
content_info
),
'content'
:
extend_content
(
content
),
content
[
'type'
]:
True
,
content
[
'type'
]:
True
,
}
}
if
cc_settings
.
MAX_COMMENT_DEPTH
is
not
None
:
if
content
[
'type'
]
==
'thread'
:
if
cc_settings
.
MAX_COMMENT_DEPTH
<
0
:
context
[
'max_depth'
]
=
True
elif
content
[
'type'
]
==
'comment'
:
if
cc_settings
.
MAX_COMMENT_DEPTH
<=
content
[
'depth'
]:
context
[
'max_depth'
]
=
True
context
=
merge_dict
(
context
,
additional_context
)
context
=
merge_dict
(
context
,
additional_context
)
partial_mustache_helpers
=
{
k
:
partial
(
v
,
content
)
for
k
,
v
in
mustache_helpers
.
items
()}
partial_mustache_helpers
=
{
k
:
partial
(
v
,
content
)
for
k
,
v
in
mustache_helpers
.
items
()}
context
=
merge_dict
(
context
,
partial_mustache_helpers
)
context
=
merge_dict
(
context
,
partial_mustache_helpers
)
...
...
lms/djangoapps/django_comment_client/mustache_helpers.py
View file @
f0737c18
...
@@ -7,7 +7,8 @@ import inspect
...
@@ -7,7 +7,8 @@ import inspect
def
pluralize
(
content
,
text
):
def
pluralize
(
content
,
text
):
num
,
word
=
text
.
split
(
' '
)
num
,
word
=
text
.
split
(
' '
)
if
int
(
num
or
'0'
)
>=
2
:
num
=
int
(
num
or
'0'
)
if
num
>=
2
or
num
==
0
:
return
word
+
's'
return
word
+
's'
else
:
else
:
return
word
return
word
...
...
lms/djangoapps/django_comment_client/settings.py
0 → 100644
View file @
f0737c18
from
django.conf
import
settings
MAX_COMMENT_DEPTH
=
None
MAX_UPLOAD_FILE_SIZE
=
1024
*
1024
#result in bytes
ALLOWED_UPLOAD_FILE_TYPES
=
(
'.jpg'
,
'.jpeg'
,
'.gif'
,
'.bmp'
,
'.png'
,
'.tiff'
)
if
hasattr
(
settings
,
'DISCUSSION_SETTINGS'
):
MAX_COMMENT_DEPTH
=
settings
.
DISCUSSION_SETTINGS
.
get
(
'MAX_COMMENT_DEPTH'
)
MAX_UPLOAD_FILE_SIZE
=
settings
.
DISCUSSION_SETTINGS
.
get
(
'MAX_UPLOAD_FILE_SIZE'
)
or
MAX_UPLOAD_FILE_SIZE
ALLOWED_UPLOAD_FILE_TYPES
=
settings
.
DISCUSSION_SETTINGS
.
get
(
'ALLOWED_UPLOAD_FILE_TYPES'
)
or
ALLOWED_UPLOAD_FILE_TYPES
lms/djangoapps/django_comment_client/utils.py
View file @
f0737c18
...
@@ -21,6 +21,8 @@ import pystache_custom as pystache
...
@@ -21,6 +21,8 @@ import pystache_custom as pystache
_FULLMODULES
=
None
_FULLMODULES
=
None
_DISCUSSIONINFO
=
None
_DISCUSSIONINFO
=
None
def
extract
(
dic
,
keys
):
def
extract
(
dic
,
keys
):
return
{
k
:
dic
.
get
(
k
)
for
k
in
keys
}
return
{
k
:
dic
.
get
(
k
)
for
k
in
keys
}
...
@@ -197,3 +199,20 @@ def url_for_tags(course_id, tags):
...
@@ -197,3 +199,20 @@ def url_for_tags(course_id, tags):
def
render_mustache
(
template_name
,
dictionary
,
*
args
,
**
kwargs
):
def
render_mustache
(
template_name
,
dictionary
,
*
args
,
**
kwargs
):
template
=
middleware
.
lookup
[
'main'
]
.
get_template
(
template_name
)
.
source
template
=
middleware
.
lookup
[
'main'
]
.
get_template
(
template_name
)
.
source
return
pystache
.
render
(
template
,
dictionary
)
return
pystache
.
render
(
template
,
dictionary
)
def
permalink
(
content
):
if
content
[
'type'
]
==
'thread'
:
return
reverse
(
'django_comment_client.forum.views.single_thread'
,
args
=
[
content
[
'course_id'
],
content
[
'commentable_id'
],
content
[
'id'
]])
else
:
return
reverse
(
'django_comment_client.forum.views.single_thread'
,
args
=
[
content
[
'course_id'
],
content
[
'commentable_id'
],
content
[
'thread_id'
]])
+
'#'
+
content
[
'id'
]
def
extend_content
(
content
):
content_info
=
{
'displayed_title'
:
content
.
get
(
'highlighted_title'
)
or
content
.
get
(
'title'
,
''
),
'displayed_body'
:
content
.
get
(
'highlighted_body'
)
or
content
.
get
(
'body'
,
''
),
'raw_tags'
:
','
.
join
(
content
.
get
(
'tags'
,
[])),
'permalink'
:
permalink
(
content
),
}
return
merge_dict
(
content
,
content_info
)
lms/envs/aws.py
View file @
f0737c18
...
@@ -68,4 +68,4 @@ if 'COURSE_ID' in ENV_TOKENS:
...
@@ -68,4 +68,4 @@ if 'COURSE_ID' in ENV_TOKENS:
ASKBOT_URL
=
"courses/{0}/discussions/"
.
format
(
ENV_TOKENS
[
'COURSE_ID'
])
ASKBOT_URL
=
"courses/{0}/discussions/"
.
format
(
ENV_TOKENS
[
'COURSE_ID'
])
COMMENTS_SERVICE_URL
=
ENV_TOKENS
[
"COMMENTS_SERVICE_URL"
]
COMMENTS_SERVICE_URL
=
ENV_TOKENS
[
"COMMENTS_SERVICE_URL"
]
COMMENTS_SERVICE_KEY
=
ENV_TOKENS
[
"COMMENTS_SERVICE_KEY"
]
lms/envs/common.py
View file @
f0737c18
...
@@ -38,6 +38,10 @@ ASKBOT_ENABLED = False
...
@@ -38,6 +38,10 @@ ASKBOT_ENABLED = False
GENERATE_RANDOM_USER_CREDENTIALS
=
False
GENERATE_RANDOM_USER_CREDENTIALS
=
False
PERFSTATS
=
False
PERFSTATS
=
False
DISCUSSION_SETTINGS
=
{
'MAX_COMMENT_DEPTH'
:
2
,
}
# Features
# Features
MITX_FEATURES
=
{
MITX_FEATURES
=
{
'SAMPLE'
:
False
,
'SAMPLE'
:
False
,
...
...
lms/envs/dev.py
View file @
f0737c18
...
@@ -92,6 +92,8 @@ SUBDOMAIN_BRANDING = {
...
@@ -92,6 +92,8 @@ SUBDOMAIN_BRANDING = {
'harvard'
:
'HarvardX'
,
'harvard'
:
'HarvardX'
,
}
}
COMMENTS_SERVICE_KEY
=
"PUT_YOUR_API_KEY_HERE"
################################ LMS Migration #################################
################################ LMS Migration #################################
MITX_FEATURES
[
'ENABLE_LMS_MIGRATION'
]
=
True
MITX_FEATURES
[
'ENABLE_LMS_MIGRATION'
]
=
True
MITX_FEATURES
[
'ACCESS_REQUIRE_STAFF_FOR_COURSE'
]
=
False
# require that user be in the staff_* group to be able to enroll
MITX_FEATURES
[
'ACCESS_REQUIRE_STAFF_FOR_COURSE'
]
=
False
# require that user be in the staff_* group to be able to enroll
...
...
lms/lib/comment_client/settings.py
View file @
f0737c18
...
@@ -7,4 +7,7 @@ else:
...
@@ -7,4 +7,7 @@ else:
PREFIX
=
SERVICE_HOST
+
'/api/v1'
PREFIX
=
SERVICE_HOST
+
'/api/v1'
API_KEY
=
"PUT_YOUR_API_KEY_HERE"
if
hasattr
(
settings
,
"COMMENTS_SERVICE_KEY"
):
API_KEY
=
settings
.
COMMENTS_SERVICE_KEY
else
:
API_KEY
=
"PUT_YOUR_API_KEY_HERE"
lms/static/coffee/src/discussion/content.coffee
View file @
f0737c18
class
@
Content
extends
Backbone
.
Model
if
Backbone
?
class
@
Content
extends
Backbone
.
Model
template
:
->
DiscussionUtil
.
getTemplate
(
'_content'
)
template
:
->
DiscussionUtil
.
getTemplate
(
'_content'
)
actions
:
actions
:
editable
:
'.admin-edit'
editable
:
'.admin-edit'
can_reply
:
'.discussion-reply'
can_reply
:
'.discussion-reply'
can_endorse
:
'.admin-endorse'
can_endorse
:
'.admin-endorse'
can_delete
:
'.admin-delete'
can_delete
:
'.admin-delete'
can_openclose
:
'.admin-openclose'
can_openclose
:
'.admin-openclose'
urlMappers
:
{}
urlMappers
:
{}
urlFor
:
(
name
)
->
urlFor
:
(
name
)
->
@
urlMappers
[
name
].
apply
(
@
)
@
urlMappers
[
name
].
apply
(
@
)
can
:
(
action
)
->
can
:
(
action
)
->
DiscussionUtil
.
getContentInfo
@
id
,
action
DiscussionUtil
.
getContentInfo
@
id
,
action
updateInfo
:
(
info
)
->
updateInfo
:
(
info
)
->
@
set
(
'ability'
,
info
.
ability
)
@
set
(
'ability'
,
info
.
ability
)
@
set
(
'voted'
,
info
.
voted
)
@
set
(
'voted'
,
info
.
voted
)
@
set
(
'subscribed'
,
info
.
subscribed
)
@
set
(
'subscribed'
,
info
.
subscribed
)
addComment
:
(
comment
,
options
)
->
addComment
:
(
comment
,
options
)
->
options
||=
{}
options
||=
{}
if
not
options
.
silent
if
not
options
.
silent
thread
=
@
get
(
'thread'
)
comments_count
=
parseInt
(
thread
.
get
(
'comments_count'
))
thread
.
set
(
'comments_count'
,
comments_count
+
1
)
@
get
(
'children'
).
push
comment
model
=
new
Comment
$
.
extend
{},
comment
,
{
thread
:
@
get
(
'thread'
)
}
@
get
(
'comments'
).
add
model
model
removeComment
:
(
comment
)
->
thread
=
@
get
(
'thread'
)
thread
=
@
get
(
'thread'
)
comments_count
=
parseInt
(
thread
.
get
(
'comments_count'
))
comments_count
=
parseInt
(
thread
.
get
(
'comments_count'
))
thread
.
set
(
'comments_count'
,
comments_count
+
1
)
thread
.
set
(
'comments_count'
,
comments_count
-
1
-
comment
.
getCommentsCount
())
@
get
(
'children'
).
push
comment
model
=
new
Comment
$
.
extend
{},
comment
,
{
thread
:
@
get
(
'thread'
)
}
@
get
(
'comments'
).
add
model
model
removeComment
:
(
comment
)
->
thread
=
@
get
(
'thread'
)
comments_count
=
parseInt
(
thread
.
get
(
'comments_count'
))
thread
.
set
(
'comments_count'
,
comments_count
-
1
-
comment
.
getCommentsCount
())
resetComments
:
(
children
)
->
@
set
'children'
,
[]
@
set
'comments'
,
new
Comments
()
for
comment
in
(
children
||
[])
@
addComment
comment
,
{
silent
:
true
}
initialize
:
->
DiscussionUtil
.
addContent
@
id
,
@
@
resetComments
(
@
get
(
'children'
))
class
@
ContentView
extends
Backbone
.
View
$
:
(
selector
)
->
@
$local
.
find
(
selector
)
partial
:
endorsed
:
(
endorsed
)
->
if
endorsed
@
$el
.
addClass
(
"endorsed"
)
else
@
$el
.
removeClass
(
"endorsed"
)
closed
:
(
closed
)
->
# we should just re-render the whole thread, or update according to new abilities
if
closed
@
$el
.
addClass
(
"closed"
)
@
$
(
".admin-openclose"
).
text
"Re-open Thread"
else
@
$el
.
removeClass
(
"closed"
)
@
$
(
".admin-openclose"
).
text
"Close Thread"
voted
:
(
voted
)
->
resetComments
:
(
children
)
->
@
$
(
".discussion-vote-up"
).
removeClass
(
"voted"
)
if
voted
!=
"up"
@
set
'children'
,
[]
@
$
(
".discussion-vote-down"
).
removeClass
(
"voted"
)
if
voted
!=
"down"
@
set
'comments'
,
new
Comments
()
@
$
(
".discussion-vote-
#{
voted
}
"
).
addClass
(
"voted"
)
if
voted
in
[
"up"
,
"down"
]
for
comment
in
(
children
||
[])
@
addComment
comment
,
{
silent
:
true
}
votes_point
:
(
votes_point
)
->
initialize
:
->
@
$
(
".discussion-votes-point"
).
html
(
votes_point
)
DiscussionUtil
.
addContent
@
id
,
@
@
resetComments
(
@
get
(
'children'
))
comments_count
:
(
comments_count
)
->
@
$
(
".comments-count"
).
html
(
comments_count
)
subscribed
:
(
subscribed
)
->
if
subscribed
@
$
(
".discussion-follow-thread"
).
addClass
(
"discussion-unfollow-thread"
).
html
(
"Unfollow"
)
else
@
$
(
".discussion-follow-thread"
).
removeClass
(
"discussion-unfollow-thread"
).
html
(
"Follow"
)
ability
:
(
ability
)
->
for
action
,
elemSelector
of
@
model
.
actions
if
not
ability
[
action
]
@
$
(
elemSelector
).
parent
().
remove
()
$discussionContent
:
->
@
_discussionContent
||=
@
$el
.
children
(
".discussion-content"
)
$showComments
:
->
@
_showComments
||=
@
$
(
".discussion-show-comments"
)
updateShowComments
:
->
if
@
showed
@
$showComments
().
html
@
$showComments
().
html
().
replace
"Show"
,
"Hide"
else
@
$showComments
().
html
@
$showComments
().
html
().
replace
"Hide"
,
"Show"
retrieved
:
->
class
@
ContentView
extends
Backbone
.
View
@
$showComments
().
hasClass
(
"retrieved"
)
$
:
(
selector
)
->
hideSingleThread
:
(
event
)
->
@
$local
.
find
(
selector
)
@
$el
.
children
(
".comments"
).
hide
()
@
showed
=
false
partial
:
@
updateShowComments
()
endorsed
:
(
endorsed
)
->
if
endorsed
showSingleThread
:
(
event
)
->
@
$el
.
addClass
(
"endorsed"
)
if
@
retrieved
()
else
@
$el
.
children
(
".comments"
).
show
()
@
$el
.
removeClass
(
"endorsed"
)
@
showed
=
true
closed
:
(
closed
)
->
# we should just re-render the whole thread, or update according to new abilities
if
closed
@
$el
.
addClass
(
"closed"
)
@
$
(
".admin-openclose"
).
text
"Re-open Thread"
else
@
$el
.
removeClass
(
"closed"
)
@
$
(
".admin-openclose"
).
text
"Close Thread"
voted
:
(
voted
)
->
@
$
(
".discussion-vote-up"
).
removeClass
(
"voted"
)
if
voted
!=
"up"
@
$
(
".discussion-vote-down"
).
removeClass
(
"voted"
)
if
voted
!=
"down"
@
$
(
".discussion-vote-
#{
voted
}
"
).
addClass
(
"voted"
)
if
voted
in
[
"up"
,
"down"
]
votes_point
:
(
votes_point
)
->
@
$
(
".discussion-votes-point"
).
html
(
votes_point
)
comments_count
:
(
comments_count
)
->
@
$
(
".comments-count"
).
html
(
comments_count
)
subscribed
:
(
subscribed
)
->
if
subscribed
@
$
(
".discussion-follow-thread"
).
addClass
(
"discussion-unfollow-thread"
).
html
(
"Unfollow"
)
else
@
$
(
".discussion-follow-thread"
).
removeClass
(
"discussion-unfollow-thread"
).
html
(
"Follow"
)
ability
:
(
ability
)
->
for
action
,
elemSelector
of
@
model
.
actions
if
not
ability
[
action
]
@
$
(
elemSelector
).
parent
().
remove
()
$discussionContent
:
->
@
_discussionContent
||=
@
$el
.
children
(
".discussion-content"
)
$showComments
:
->
@
_showComments
||=
@
$
(
".discussion-show-comments"
)
updateShowComments
:
->
if
@
showed
@
$showComments
().
html
@
$showComments
().
html
().
replace
"Show"
,
"Hide"
else
@
$showComments
().
html
@
$showComments
().
html
().
replace
"Hide"
,
"Show"
retrieved
:
->
@
$showComments
().
hasClass
(
"retrieved"
)
hideSingleThread
:
(
event
)
->
@
$el
.
children
(
".comments"
).
hide
()
@
showed
=
false
@
updateShowComments
()
@
updateShowComments
()
else
$elem
=
$
.
merge
@
$
(
".thread-title"
),
@
$showComments
()
showSingleThread
:
(
event
)
->
url
=
@
model
.
urlFor
(
'retrieve'
)
if
@
retrieved
(
)
DiscussionUtil
.
get
$elem
,
url
,
{},
(
response
,
textStatus
)
=>
@
$el
.
children
(
".comments"
).
show
()
@
showed
=
true
@
showed
=
true
@
updateShowComments
()
@
updateShowComments
()
@
$showComments
().
addClass
(
"retrieved"
)
else
@
$el
.
children
(
".comments"
).
replaceWith
response
.
html
$elem
=
$
.
merge
@
$
(
".thread-title"
),
@
$showComments
()
@
model
.
resetComments
response
.
content
.
children
url
=
@
model
.
urlFor
(
'retrieve'
)
@
initCommentViews
()
DiscussionUtil
.
safeAjax
DiscussionUtil
.
bulkUpdateContentInfo
response
.
annotated_content_info
$elem
:
$elem
$loading
:
$
(
event
.
target
)
if
event
toggleSingleThread
:
(
event
)
->
type
:
"GET"
if
@
showed
url
:
url
@
hideSingleThread
(
event
)
success
:
(
response
,
textStatus
)
=>
else
@
showed
=
true
@
showSingleThread
(
event
)
@
updateShowComments
()
@
$showComments
().
addClass
(
"retrieved"
)
initCommentViews
:
->
@
$el
.
children
(
".comments"
).
replaceWith
response
.
html
@
$el
.
children
(
".comments"
).
children
(
".comment"
).
each
(
index
,
elem
)
=>
@
model
.
resetComments
response
.
content
.
children
model
=
@
model
.
get
(
'comments'
).
find
$
(
elem
).
attr
(
"_id"
)
@
initCommentViews
()
if
not
model
.
view
DiscussionUtil
.
bulkUpdateContentInfo
response
.
annotated_content_info
commentView
=
new
CommentView
el
:
elem
,
model
:
model
toggleSingleThread
:
(
event
)
->
reply
:
->
if
@
showed
if
@
model
.
get
(
'type'
)
==
'thread'
@
hideSingleThread
(
event
)
@
showSingleThread
()
else
$replyView
=
@
$
(
".discussion-reply-new"
)
@
showSingleThread
(
event
)
if
$replyView
.
length
$replyView
.
show
()
initCommentViews
:
->
else
@
$el
.
children
(
".comments"
).
children
(
".comment"
).
each
(
index
,
elem
)
=>
view
=
{}
model
=
@
model
.
get
(
'comments'
).
find
$
(
elem
).
attr
(
"_id"
)
view
.
id
=
@
model
.
id
if
not
model
.
view
view
.
showWatchCheckbox
=
not
@
model
.
get
(
'thread'
).
get
(
'subscribed'
)
commentView
=
new
CommentView
el
:
elem
,
model
:
model
html
=
Mustache
.
render
DiscussionUtil
.
getTemplate
(
'_reply'
),
view
@
$discussionContent
().
append
html
reply
:
->
DiscussionUtil
.
makeWmdEditor
@
$el
,
$
.
proxy
(
@
$
,
@
),
"reply-body"
if
@
model
.
get
(
'type'
)
==
'thread'
@
$
(
".discussion-submit-post"
).
click
$
.
proxy
(
@
submitReply
,
@
)
@
showSingleThread
()
@
$
(
".discussion-cancel-post"
).
click
$
.
proxy
(
@
cancelReply
,
@
)
$replyView
=
@
$
(
".discussion-reply-new"
)
@
$
(
".discussion-reply"
).
hide
()
if
$replyView
.
length
@
$
(
".discussion-edit"
).
hide
()
$replyView
.
show
()
else
submitReply
:
(
event
)
->
view
=
{}
url
=
@
model
.
urlFor
(
'reply'
)
view
.
id
=
@
model
.
id
view
.
showWatchCheckbox
=
not
@
model
.
get
(
'thread'
).
get
(
'subscribed'
)
body
=
DiscussionUtil
.
getWmdContent
@
$el
,
$
.
proxy
(
@
$
,
@
),
"reply-body"
html
=
Mustache
.
render
DiscussionUtil
.
getTemplate
(
'_reply'
),
view
@
$discussionContent
().
append
html
anonymous
=
false
||
@
$
(
".discussion-post-anonymously"
).
is
(
":checked"
)
DiscussionUtil
.
makeWmdEditor
@
$el
,
$
.
proxy
(
@
$
,
@
),
"reply-body"
autowatch
=
false
||
@
$
(
".discussion-auto-watch"
).
is
(
":checked"
)
@
$
(
".discussion-submit-post"
).
click
$
.
proxy
(
@
submitReply
,
@
)
@
$
(
".discussion-cancel-post"
).
click
$
.
proxy
(
@
cancelReply
,
@
)
DiscussionUtil
.
safeAjax
@
$
(
".discussion-reply"
).
hide
()
$elem
:
$
(
event
.
target
)
@
$
(
".discussion-edit"
).
hide
()
url
:
url
type
:
"POST"
submitReply
:
(
event
)
->
dataType
:
'json'
url
=
@
model
.
urlFor
(
'reply'
)
data
:
body
:
body
body
=
DiscussionUtil
.
getWmdContent
@
$el
,
$
.
proxy
(
@
$
,
@
),
"reply-body"
anonymous
:
anonymous
auto_subscribe
:
autowatch
anonymous
=
false
||
@
$
(
".discussion-post-anonymously"
).
is
(
":checked"
)
error
:
DiscussionUtil
.
formErrorHandler
@
$
(
".discussion-errors"
)
autowatch
=
false
||
@
$
(
".discussion-auto-watch"
).
is
(
":checked"
)
success
:
(
response
,
textStatus
)
=>
DiscussionUtil
.
clearFormErrors
@
$
(
".discussion-errors"
)
DiscussionUtil
.
safeAjax
$comment
=
$
(
response
.
html
)
$elem
:
$
(
event
.
target
)
@
$el
.
children
(
".comments"
).
prepend
$comment
$loading
:
$
(
event
.
target
)
if
event
DiscussionUtil
.
setWmdContent
@
$el
,
$
.
proxy
(
@
$
,
@
),
"reply-body"
,
""
url
:
url
comment
=
@
model
.
addComment
response
.
content
type
:
"POST"
commentView
=
new
CommentView
el
:
$comment
[
0
],
model
:
comment
dataType
:
'json'
comment
.
updateInfo
response
.
annotated_content_info
data
:
@
cancelReply
()
body
:
body
anonymous
:
anonymous
cancelReply
:
->
auto_subscribe
:
autowatch
$replyView
=
@
$
(
".discussion-reply-new"
)
error
:
DiscussionUtil
.
formErrorHandler
@
$
(
".discussion-errors"
)
if
$replyView
.
length
success
:
(
response
,
textStatus
)
=>
$replyView
.
hide
()
DiscussionUtil
.
clearFormErrors
@
$
(
".discussion-errors"
)
@
$
(
".discussion-reply"
).
show
()
$comment
=
$
(
response
.
html
)
@
$
(
".discussion-edit"
).
show
()
@
$el
.
children
(
".comments"
).
prepend
$comment
DiscussionUtil
.
setWmdContent
@
$el
,
$
.
proxy
(
@
$
,
@
),
"reply-body"
,
""
unvote
:
(
event
)
->
comment
=
@
model
.
addComment
response
.
content
url
=
@
model
.
urlFor
(
'unvote'
)
commentView
=
new
CommentView
el
:
$comment
[
0
],
model
:
comment
$elem
=
@
$
(
".discussion-vote"
)
comment
.
updateInfo
response
.
annotated_content_info
DiscussionUtil
.
post
$elem
,
url
,
{},
(
response
,
textStatus
)
=>
@
cancelReply
()
@
model
.
set
(
'voted'
,
''
)
@
model
.
set
(
'votes_point'
,
response
.
votes
.
point
)
cancelReply
:
->
$replyView
=
@
$
(
".discussion-reply-new"
)
vote
:
(
event
,
value
)
->
if
$replyView
.
length
url
=
@
model
.
urlFor
(
"
#{
value
}
vote"
)
$replyView
.
hide
()
$elem
=
@
$
(
".discussion-vote"
)
@
$
(
".discussion-reply"
).
show
()
DiscussionUtil
.
post
$elem
,
url
,
{},
(
response
,
textStatus
)
=>
@
$
(
".discussion-edit"
).
show
()
@
model
.
set
(
'voted'
,
value
)
@
model
.
set
(
'votes_point'
,
response
.
votes
.
point
)
unvote
:
(
event
)
->
url
=
@
model
.
urlFor
(
'unvote'
)
toggleVote
:
(
event
)
->
$elem
=
@
$
(
".discussion-vote"
)
$elem
=
$
(
event
.
target
)
DiscussionUtil
.
safeAjax
value
=
$elem
.
attr
(
"value"
)
$elem
:
$elem
if
@
model
.
get
(
"voted"
)
==
value
url
:
url
@
unvote
(
event
)
type
:
"POST"
else
success
:
(
response
,
textStatus
)
=>
@
vote
(
event
,
value
)
@
model
.
set
(
'voted'
,
''
)
@
model
.
set
(
'votes_point'
,
response
.
votes
.
point
)
toggleEndorse
:
(
event
)
->
$elem
=
$
(
event
.
target
)
vote
:
(
event
,
value
)
->
url
=
@
model
.
urlFor
(
'endorse'
)
url
=
@
model
.
urlFor
(
"
#{
value
}
vote"
)
endorsed
=
@
model
.
get
(
'endorsed'
)
$elem
=
@
$
(
".discussion-vote"
)
data
=
{
endorsed
:
not
endorsed
}
DiscussionUtil
.
safeAjax
DiscussionUtil
.
post
$elem
,
url
,
data
,
(
response
,
textStatus
)
=>
$elem
:
$elem
@
model
.
set
(
'endorsed'
,
not
endorsed
)
url
:
url
type
:
"POST"
toggleFollow
:
(
event
)
->
success
:
(
response
,
textStatus
)
=>
$elem
=
$
(
event
.
target
)
@
model
.
set
(
'voted'
,
value
)
subscribed
=
@
model
.
get
(
'subscribed'
)
@
model
.
set
(
'votes_point'
,
response
.
votes
.
point
)
if
subscribed
url
=
@
model
.
urlFor
(
'unfollow'
)
toggleVote
:
(
event
)
->
else
$elem
=
$
(
event
.
target
)
url
=
@
model
.
urlFor
(
'follow'
)
value
=
$elem
.
attr
(
"value"
)
DiscussionUtil
.
post
$elem
,
url
,
{},
(
response
,
textStatus
)
=>
if
@
model
.
get
(
"voted"
)
==
value
@
model
.
set
(
'subscribed'
,
not
subscribed
)
@
unvote
(
event
)
else
toggleClosed
:
(
event
)
->
@
vote
(
event
,
value
)
$elem
=
$
(
event
.
target
)
url
=
@
model
.
urlFor
(
'close'
)
toggleEndorse
:
(
event
)
->
closed
=
@
model
.
get
(
'closed'
)
$elem
=
$
(
event
.
target
)
data
=
{
closed
:
not
closed
}
url
=
@
model
.
urlFor
(
'endorse'
)
DiscussionUtil
.
post
$elem
,
url
,
data
,
(
response
,
textStatus
)
=>
endorsed
=
@
model
.
get
(
'endorsed'
)
@
model
.
set
(
'closed'
,
not
closed
)
data
=
{
endorsed
:
not
endorsed
}
DiscussionUtil
.
safeAjax
edit
:
(
event
)
->
$elem
:
$elem
@
$
(
".discussion-content-wrapper"
).
hide
()
url
:
url
$editView
=
@
$
(
".discussion-content-edit"
)
data
:
data
if
$editView
.
length
type
:
"POST"
$editView
.
show
()
success
:
(
response
,
textStatus
)
=>
else
@
model
.
set
(
'endorsed'
,
not
endorsed
)
view
=
{}
view
.
id
=
@
model
.
id
toggleFollow
:
(
event
)
->
$elem
=
$
(
event
.
target
)
subscribed
=
@
model
.
get
(
'subscribed'
)
if
subscribed
url
=
@
model
.
urlFor
(
'unfollow'
)
else
url
=
@
model
.
urlFor
(
'follow'
)
DiscussionUtil
.
safeAjax
$elem
:
$elem
url
:
url
type
:
"POST"
success
:
(
response
,
textStatus
)
=>
@
model
.
set
(
'subscribed'
,
not
subscribed
)
toggleClosed
:
(
event
)
->
$elem
=
$
(
event
.
target
)
url
=
@
model
.
urlFor
(
'close'
)
closed
=
@
model
.
get
(
'closed'
)
data
=
{
closed
:
not
closed
}
DiscussionUtil
.
safeAjax
$elem
:
$elem
url
:
url
type
:
"POST"
data
:
data
success
:
(
response
,
textStatus
)
=>
@
model
.
set
(
'closed'
,
not
closed
)
edit
:
(
event
)
->
@
$
(
".discussion-content-wrapper"
).
hide
()
$editView
=
@
$
(
".discussion-content-edit"
)
if
$editView
.
length
$editView
.
show
()
else
view
=
{}
view
.
id
=
@
model
.
id
if
@
model
.
get
(
'type'
)
==
'thread'
view
.
title
=
@
$
(
".thread-raw-title"
).
html
()
view
.
body
=
@
$
(
".thread-raw-body"
).
html
()
view
.
tags
=
@
$
(
".thread-raw-tags"
).
html
()
else
view
.
body
=
@
$
(
".comment-raw-body"
).
html
()
@
$discussionContent
().
append
Mustache
.
render
DiscussionUtil
.
getTemplate
(
"_edit_
#{
@
model
.
get
(
'type'
)
}
"
),
view
DiscussionUtil
.
makeWmdEditor
@
$el
,
$
.
proxy
(
@
$
,
@
),
"
#{
@
model
.
get
(
'type'
)
}
-body-edit"
@
$
(
".thread-tags-edit"
).
tagsInput
DiscussionUtil
.
tagsInputOptions
()
@
$
(
".discussion-submit-update"
).
unbind
(
"click"
).
click
$
.
proxy
(
@
submitEdit
,
@
)
@
$
(
".discussion-cancel-update"
).
unbind
(
"click"
).
click
$
.
proxy
(
@
cancelEdit
,
@
)
submitEdit
:
(
event
)
->
url
=
@
model
.
urlFor
(
'update'
)
data
=
{}
if
@
model
.
get
(
'type'
)
==
'thread'
data
.
title
=
@
$
(
".thread-title-edit"
).
val
()
data
.
body
=
DiscussionUtil
.
getWmdContent
@
$el
,
$
.
proxy
(
@
$
,
@
),
"thread-body-edit"
data
.
tags
=
@
$
(
".thread-tags-edit"
).
val
()
else
data
.
body
=
DiscussionUtil
.
getWmdContent
@
$el
,
$
.
proxy
(
@
$
,
@
),
"comment-body-edit"
DiscussionUtil
.
safeAjax
$elem
:
$
(
event
.
target
)
$loading
:
$
(
event
.
target
)
if
event
url
:
url
type
:
"POST"
dataType
:
'json'
data
:
data
error
:
DiscussionUtil
.
formErrorHandler
@
$
(
".discussion-update-errors"
)
success
:
(
response
,
textStatus
)
=>
DiscussionUtil
.
clearFormErrors
@
$
(
".discussion-update-errors"
)
@
$discussionContent
().
replaceWith
(
response
.
html
)
@
model
.
set
response
.
content
@
model
.
updateInfo
response
.
annotated_content_info
cancelEdit
:
(
event
)
->
@
$
(
".discussion-content-edit"
).
hide
()
@
$
(
".discussion-content-wrapper"
).
show
()
delete
:
(
event
)
->
url
=
@
model
.
urlFor
(
'delete'
)
if
@
model
.
get
(
'type'
)
==
'thread'
if
@
model
.
get
(
'type'
)
==
'thread'
view
.
title
=
@
$
(
".thread-raw-title"
).
html
()
c
=
confirm
"Are you sure to delete thread
\"
#{
@
model
.
get
(
'title'
)
}
\"
?"
view
.
body
=
@
$
(
".thread-raw-body"
).
html
()
view
.
tags
=
@
$
(
".thread-raw-tags"
).
html
()
else
else
view
.
body
=
@
$
(
".comment-raw-body"
).
html
()
c
=
confirm
"Are you sure to delete this comment? "
@
$discussionContent
().
append
Mustache
.
render
DiscussionUtil
.
getTemplate
(
"_edit_
#{
@
model
.
get
(
'type'
)
}
"
),
view
if
not
c
Discussion
.
makeWmdEditor
@
$el
,
$
.
proxy
(
@
$
,
@
),
"
#{
@
model
.
get
(
'type'
)
}
-body-edit"
return
@
$
(
".thread-tags-edit"
).
tagsInput
DiscussionUtil
.
tagsInputOptions
()
$elem
=
$
(
event
.
target
)
@
$
(
".discussion-submit-update"
).
unbind
(
"click"
).
click
$
.
proxy
(
@
submitEdit
,
@
)
DiscussionUtil
.
safeAjax
@
$
(
".discussion-cancel-update"
).
unbind
(
"click"
).
click
$
.
proxy
(
@
cancelEdit
,
@
)
$elem
:
$elem
url
:
url
submitEdit
:
(
event
)
->
success
:
(
response
,
textStatus
)
=>
@
$el
.
remove
()
url
=
@
model
.
urlFor
(
'update'
)
@
model
.
get
(
'thread'
).
removeComment
(
@
model
)
data
=
{}
if
@
model
.
get
(
'type'
)
==
'thread'
events
:
data
.
title
=
@
$
(
".thread-title-edit"
).
val
()
"click .discussion-follow-thread"
:
"toggleFollow"
data
.
body
=
DiscussionUtil
.
getWmdContent
@
$el
,
$
.
proxy
(
@
$
,
@
),
"thread-body-edit"
"click .thread-title"
:
"toggleSingleThread"
data
.
tags
=
@
$
(
".thread-tags-edit"
).
val
()
"click .discussion-show-comments"
:
"toggleSingleThread"
else
"click .discussion-reply-thread"
:
"reply"
data
.
body
=
DiscussionUtil
.
getWmdContent
@
$el
,
$
.
proxy
(
@
$
,
@
),
"comment-body-edit"
"click .discussion-reply-comment"
:
"reply"
DiscussionUtil
.
safeAjax
"click .discussion-cancel-reply"
:
"cancelReply"
$elem
:
$
(
event
.
target
)
"click .discussion-vote-up"
:
"toggleVote"
url
:
url
"click .discussion-vote-down"
:
"toggleVote"
type
:
"POST"
"click .admin-endorse"
:
"toggleEndorse"
dataType
:
'json'
"click .admin-openclose"
:
"toggleClosed"
data
:
data
"click .admin-edit"
:
"edit"
error
:
DiscussionUtil
.
formErrorHandler
@
$
(
".discussion-update-errors"
)
"click .admin-delete"
:
"delete"
success
:
(
response
,
textStatus
)
=>
DiscussionUtil
.
clearFormErrors
@
$
(
".discussion-update-errors"
)
initLocal
:
->
@
$discussionContent
().
replaceWith
(
response
.
html
)
@
$local
=
@
$el
.
children
(
".local"
)
@
model
.
set
response
.
content
@
$delegateElement
=
@
$local
@
model
.
updateInfo
response
.
annotated_content_info
initTitle
:
->
cancelEdit
:
(
event
)
->
$contentTitle
=
@
$
(
".thread-title"
)
@
$
(
".discussion-content-edit"
).
hide
()
if
$contentTitle
.
length
@
$
(
".discussion-content-wrapper"
).
show
()
$contentTitle
.
html
DiscussionUtil
.
unescapeHighlightTag
DiscussionUtil
.
stripLatexHighlight
$contentTitle
.
html
()
delete
:
(
event
)
->
initBody
:
->
url
=
@
model
.
urlFor
(
'delete'
)
$contentBody
=
@
$
(
".content-body"
)
if
@
model
.
get
(
'type'
)
==
'thread'
$contentBody
.
html
DiscussionUtil
.
postMathJaxProcessor
DiscussionUtil
.
markdownWithHighlight
$contentBody
.
html
()
c
=
confirm
"Are you sure to delete thread
\"
#{
@
model
.
get
(
'title'
)
}
\"
?"
MathJax
.
Hub
.
Queue
[
"Typeset"
,
MathJax
.
Hub
,
$contentBody
.
attr
(
"id"
)]
else
c
=
confirm
"Are you sure to delete this comment? "
initTimeago
:
->
if
not
c
@
$
(
"span.timeago"
).
timeago
()
return
$elem
=
$
(
event
.
target
)
renderPartial
:
->
DiscussionUtil
.
post
$elem
,
url
,
{},
(
response
,
textStatus
)
=>
for
attr
,
value
of
@
model
.
changedAttributes
()
@
$el
.
remove
()
if
@
partial
[
attr
]
@
model
.
get
(
'thread'
).
removeComment
(
@
model
)
@
partial
[
attr
].
apply
(
@
,
[
value
])
initBindings
:
->
@
model
.
view
=
@
@
model
.
bind
(
'change'
,
@
renderPartial
,
@
)
initialize
:
->
@
initBindings
()
@
initLocal
()
@
initTimeago
()
@
initTitle
()
@
initBody
()
@
initCommentViews
()
events
:
class
@
Thread
extends
@
Content
"click .discussion-follow-thread"
:
"toggleFollow"
urlMappers
:
"click .thread-title"
:
"toggleSingleThread"
'retrieve'
:
->
DiscussionUtil
.
urlFor
(
'retrieve_single_thread'
,
@
discussion
.
id
,
@
id
)
"click .discussion-show-comments"
:
"toggleSingleThread"
'reply'
:
->
DiscussionUtil
.
urlFor
(
'create_comment'
,
@
id
)
"click .discussion-reply-thread"
:
"reply"
'unvote'
:
->
DiscussionUtil
.
urlFor
(
"undo_vote_for_
#{
@
get
(
'type'
)
}
"
,
@
id
)
"click .discussion-reply-comment"
:
"reply"
'upvote'
:
->
DiscussionUtil
.
urlFor
(
"upvote_
#{
@
get
(
'type'
)
}
"
,
@
id
)
"click .discussion-cancel-reply"
:
"cancelReply"
'downvote'
:
->
DiscussionUtil
.
urlFor
(
"downvote_
#{
@
get
(
'type'
)
}
"
,
@
id
)
"click .discussion-vote-up"
:
"toggleVote"
'close'
:
->
DiscussionUtil
.
urlFor
(
'openclose_thread'
,
@
id
)
"click .discussion-vote-down"
:
"toggleVote"
'update'
:
->
DiscussionUtil
.
urlFor
(
'update_thread'
,
@
id
)
"click .admin-endorse"
:
"toggleEndorse"
'delete'
:
->
DiscussionUtil
.
urlFor
(
'delete_thread'
,
@
id
)
"click .admin-openclose"
:
"toggleClosed"
'follow'
:
->
DiscussionUtil
.
urlFor
(
'follow_thread'
,
@
id
)
"click .admin-edit"
:
"edit"
'unfollow'
:
->
DiscussionUtil
.
urlFor
(
'unfollow_thread'
,
@
id
)
"click .admin-delete"
:
"delete"
initialize
:
->
initLocal
:
->
@
set
(
'thread'
,
@
)
@
$local
=
@
$el
.
children
(
".local"
)
super
()
@
$delegateElement
=
@
$local
class
@
ThreadView
extends
@
ContentView
initTitle
:
->
$contentTitle
=
@
$
(
".thread-title"
)
class
@
Comment
extends
@
Content
if
$contentTitle
.
length
urlMappers
:
$contentTitle
.
html
DiscussionUtil
.
unescapeHighlightTag
DiscussionUtil
.
stripLatexHighlight
$contentTitle
.
html
()
'reply'
:
->
DiscussionUtil
.
urlFor
(
'create_sub_comment'
,
@
id
)
'unvote'
:
->
DiscussionUtil
.
urlFor
(
"undo_vote_for_
#{
@
get
(
'type'
)
}
"
,
@
id
)
initBody
:
->
'upvote'
:
->
DiscussionUtil
.
urlFor
(
"upvote_
#{
@
get
(
'type'
)
}
"
,
@
id
)
$contentBody
=
@
$
(
".content-body"
)
'downvote'
:
->
DiscussionUtil
.
urlFor
(
"downvote_
#{
@
get
(
'type'
)
}
"
,
@
id
)
$contentBody
.
html
DiscussionUtil
.
postMathJaxProcessor
DiscussionUtil
.
markdownWithHighlight
$contentBody
.
html
()
'endorse'
:
->
DiscussionUtil
.
urlFor
(
'endorse_comment'
,
@
id
)
MathJax
.
Hub
.
Queue
[
"Typeset"
,
MathJax
.
Hub
,
$contentBody
.
attr
(
"id"
)]
'update'
:
->
DiscussionUtil
.
urlFor
(
'update_comment'
,
@
id
)
'delete'
:
->
DiscussionUtil
.
urlFor
(
'delete_comment'
,
@
id
)
initTimeago
:
->
@
$
(
"span.timeago"
).
timeago
()
getCommentsCount
:
->
count
=
0
initPermalink
:
->
@
get
(
'comments'
).
each
(
comment
)
->
@
$
(
".discussion-permanent-link"
).
attr
"href"
,
@
model
.
permalink
()
count
+=
comment
.
getCommentsCount
()
+
1
count
renderPartial
:
->
for
attr
,
value
of
@
model
.
changedAttributes
()
class
@
CommentView
extends
@
ContentView
if
@
partial
[
attr
]
@
partial
[
attr
].
apply
(
@
,
[
value
])
class
@
Comments
extends
Backbone
.
Collection
initBindings
:
->
model
:
Comment
@
model
.
view
=
@
@
model
.
bind
(
'change'
,
@
renderPartial
,
@
)
initialize
:
->
@
bind
"add"
,
(
item
)
=>
initialize
:
->
item
.
collection
=
@
@
initBindings
()
@
initLocal
()
find
:
(
id
)
->
@
initTimeago
()
_
.
first
@
where
(
id
:
id
)
@
initTitle
()
@
initBody
()
@
initCommentViews
()
class
@
Thread
extends
@
Content
urlMappers
:
'retrieve'
:
->
DiscussionUtil
.
urlFor
(
'retrieve_single_thread'
,
@
discussion
.
id
,
@
id
)
'reply'
:
->
DiscussionUtil
.
urlFor
(
'create_comment'
,
@
id
)
'unvote'
:
->
DiscussionUtil
.
urlFor
(
"undo_vote_for_
#{
@
get
(
'type'
)
}
"
,
@
id
)
'upvote'
:
->
DiscussionUtil
.
urlFor
(
"upvote_
#{
@
get
(
'type'
)
}
"
,
@
id
)
'downvote'
:
->
DiscussionUtil
.
urlFor
(
"downvote_
#{
@
get
(
'type'
)
}
"
,
@
id
)
'close'
:
->
DiscussionUtil
.
urlFor
(
'openclose_thread'
,
@
id
)
'update'
:
->
DiscussionUtil
.
urlFor
(
'update_thread'
,
@
id
)
'delete'
:
->
DiscussionUtil
.
urlFor
(
'delete_thread'
,
@
id
)
'follow'
:
->
DiscussionUtil
.
urlFor
(
'follow_thread'
,
@
id
)
'unfollow'
:
->
DiscussionUtil
.
urlFor
(
'unfollow_thread'
,
@
id
)
initialize
:
->
@
set
(
'thread'
,
@
)
super
()
permalink
:
->
discussion_id
=
@
get
(
'commentable_id'
)
return
Discussion
.
urlFor
(
"permanent_link_thread"
,
discussion_id
,
@
id
)
class
@
ThreadView
extends
@
ContentView
class
@
Comment
extends
@
Content
urlMappers
:
'reply'
:
->
DiscussionUtil
.
urlFor
(
'create_sub_comment'
,
@
id
)
'unvote'
:
->
DiscussionUtil
.
urlFor
(
"undo_vote_for_
#{
@
get
(
'type'
)
}
"
,
@
id
)
'upvote'
:
->
DiscussionUtil
.
urlFor
(
"upvote_
#{
@
get
(
'type'
)
}
"
,
@
id
)
'downvote'
:
->
DiscussionUtil
.
urlFor
(
"downvote_
#{
@
get
(
'type'
)
}
"
,
@
id
)
'endorse'
:
->
DiscussionUtil
.
urlFor
(
'endorse_comment'
,
@
id
)
'update'
:
->
DiscussionUtil
.
urlFor
(
'update_comment'
,
@
id
)
'delete'
:
->
DiscussionUtil
.
urlFor
(
'delete_comment'
,
@
id
)
permalink
:
->
thread_id
=
@
get
(
'thread'
).
id
discussion_id
=
@
get
(
'thread'
).
get
(
'commentable_id'
)
return
Discussion
.
urlFor
(
"permanent_link_comment"
,
discussion_id
,
thread_id
,
@
id
)
getCommentsCount
:
->
count
=
0
@
get
(
'comments'
).
each
(
comment
)
->
count
+=
comment
.
getCommentsCount
()
+
1
count
class
@
CommentView
extends
@
ContentView
class
@
Comments
extends
Backbone
.
Collection
model
:
Comment
initialize
:
->
@
bind
"add"
,
(
item
)
=>
item
.
collection
=
@
find
:
(
id
)
->
_
.
first
@
where
(
id
:
id
)
lms/static/coffee/src/discussion/discussion.coffee
View file @
f0737c18
class
@
Discussion
extends
Backbone
.
Collection
if
Backbone
?
model
:
Thread
class
@
Discussion
extends
Backbone
.
Collection
model
:
Thread
initialize
:
->
DiscussionUtil
.
addDiscussion
@
id
,
@
initialize
:
->
@
bind
"add"
,
(
item
)
=>
DiscussionUtil
.
addDiscussion
@
id
,
@
item
.
discussion
=
@
@
bind
"add"
,
(
item
)
=>
item
.
discussion
=
@
find
:
(
id
)
->
_
.
first
@
where
(
id
:
id
)
find
:
(
id
)
->
_
.
first
@
where
(
id
:
id
)
addThread
:
(
thread
,
options
)
->
options
||=
{}
addThread
:
(
thread
,
options
)
->
model
=
new
Thread
thread
options
||=
{}
@
add
model
model
=
new
Thread
thread
model
@
add
model
model
class
@
DiscussionView
extends
Backbone
.
View
class
@
DiscussionView
extends
Backbone
.
View
$
:
(
selector
)
->
@
$local
.
find
(
selector
)
$
:
(
selector
)
->
@
$local
.
find
(
selector
)
initLocal
:
->
@
$local
=
@
$el
.
children
(
".local"
)
initLocal
:
->
@
$delegateElement
=
@
$local
@
$local
=
@
$el
.
children
(
".local"
)
@
$delegateElement
=
@
$local
initialize
:
->
@
initLocal
()
initialize
:
->
@
model
.
id
=
@
$el
.
attr
(
"_id"
)
@
initLocal
(
)
@
model
.
view
=
@
@
model
.
id
=
@
$el
.
attr
(
"_id"
)
@
$el
.
children
(
".threads"
).
children
(
".thread"
).
each
(
index
,
elem
)
=>
@
model
.
view
=
@
threadView
=
new
ThreadView
el
:
elem
,
model
:
@
model
.
find
$
(
elem
).
attr
(
"_id"
)
@
$el
.
children
(
".threads"
).
children
(
".thread"
).
each
(
index
,
elem
)
=>
if
@
$el
.
hasClass
(
"forum-discussion
"
)
threadView
=
new
ThreadView
el
:
elem
,
model
:
@
model
.
find
$
(
elem
).
attr
(
"_id
"
)
$
(
".discussion-sidebar"
).
find
(
".sidebar-new-post-butt
on"
)
if
@
$el
.
hasClass
(
"forum-discussi
on"
)
.
unbind
(
'click'
).
click
$
.
proxy
@
newPost
,
@
$
(
".discussion-sidebar"
).
find
(
".sidebar-new-post-button"
)
else
if
@
$el
.
hasClass
(
"inline-discussion"
)
.
unbind
(
'click'
).
click
$
.
proxy
@
newPost
,
@
@
newPost
(
)
else
if
@
$el
.
hasClass
(
"inline-discussion"
)
@
newPost
()
reload
:
(
$elem
,
url
)
->
if
not
url
then
return
reload
:
(
$elem
,
url
)
->
DiscussionUtil
.
get
$elem
,
url
,
{},
(
response
,
textStatus
)
=>
if
not
url
then
return
$parent
=
@
$el
.
parent
()
DiscussionUtil
.
safeAjax
@
$el
.
replaceWith
(
response
.
html
)
$elem
:
$elem
$discussion
=
$parent
.
find
(
"section.discussion"
)
$loading
:
$elem
@
model
.
reset
(
response
.
discussionData
,
{
silent
:
false
})
url
:
url
view
=
new
DiscussionView
el
:
$discussion
[
0
],
model
:
@
model
type
:
"GET"
DiscussionUtil
.
bulkUpdateContentInfo
(
window
.
$
$annotated_content_info
)
success
:
(
response
,
textStatus
)
=>
$parent
=
@
$el
.
parent
()
loadSimilarPost
:
(
event
)
->
@
$el
.
replaceWith
(
response
.
html
)
$title
=
@
$
(
".new-post-title
"
)
$discussion
=
$parent
.
find
(
"section.discussion
"
)
$wrapper
=
@
$
(
".new-post-similar-posts-wrapper"
)
@
model
.
reset
(
response
.
discussionData
,
{
silent
:
false
}
)
$similarPosts
=
@
$
(
".new-post-similar-posts"
)
view
=
new
DiscussionView
el
:
$discussion
[
0
],
model
:
@
model
prevText
=
$title
.
attr
(
"prev-text"
)
DiscussionUtil
.
bulkUpdateContentInfo
(
window
.
$
$annotated_content_info
)
text
=
$title
.
val
(
)
$
(
"html, body"
).
animate
({
scrollTop
:
0
},
0
)
if
text
==
prevText
if
@
$
(
".similar-post"
).
length
loadSimilarPost
:
(
event
)
->
$wrapper
.
show
()
console
.
log
"loading similar"
else
if
$
.
trim
(
text
).
length
$title
=
@
$
(
".new-post-title"
)
$
elem
=
$
(
event
.
target
)
$
wrapper
=
@
$
(
".new-post-similar-posts-wrapper"
)
url
=
DiscussionUtil
.
urlFor
'search_similar_threads'
,
@
model
.
id
$similarPosts
=
@
$
(
".new-post-similar-posts"
)
data
=
{
text
:
@
$
(
".new-post-title"
).
val
()
}
prevText
=
$title
.
attr
(
"prev-text"
)
DiscussionUtil
.
get
$elem
,
url
,
data
,
(
response
,
textStatus
)
=>
text
=
$title
.
val
()
$similarPosts
.
empty
()
if
text
==
prevText
if
$
.
type
(
response
)
==
"array"
and
response
.
length
if
@
$
(
".similar-post"
)
.
length
$wrapper
.
show
()
$wrapper
.
show
()
for
thread
in
response
else
if
$
.
trim
(
text
).
length
$similarPost
=
$
(
"<a>"
).
addClass
(
"similar-post"
)
$elem
=
$
(
event
.
target
)
.
html
(
thread
[
"title"
])
url
=
DiscussionUtil
.
urlFor
'search_similar_threads'
,
@
model
.
id
.
attr
(
"href"
,
"javascript:void(0)"
)
#TODO
data
=
{
text
:
@
$
(
".new-post-title"
).
val
()
}
.
appendTo
(
$similarPosts
)
DiscussionUtil
.
safeAjax
else
$elem
:
$elem
$wrapper
.
hide
()
url
:
url
else
data
:
data
$wrapper
.
hide
()
dataType
:
'json'
$title
.
attr
(
"prev-text"
,
text
)
success
:
(
response
,
textStatus
)
=>
$wrapper
.
html
(
response
.
html
)
if
$wrapper
.
find
(
".similar-post"
).
length
newPost
:
->
$wrapper
.
show
()
if
not
@
$
(
".wmd-panel"
).
length
$wrapper
.
find
(
".hide-similar-posts"
).
click
=>
view
=
{
discussion_id
:
@
model
.
id
}
$wrapper
.
hide
()
@
$el
.
children
(
".discussion-non-content"
).
append
Mustache
.
render
DiscussionUtil
.
getTemplate
(
"_new_post"
),
view
else
$newPostBody
=
@
$
(
".new-post-body"
)
$wrapper
.
hide
()
DiscussionUtil
.
makeWmdEditor
@
$el
,
$
.
proxy
(
@
$
,
@
),
"new-post-body"
$title
.
attr
(
"prev-text"
,
text
)
$input
=
DiscussionUtil
.
getWmdInput
@
$el
,
$
.
proxy
(
@
$
,
@
),
"new-post-body"
$input
.
attr
(
"placeholder"
,
"post a new topic..."
)
newPost
:
->
if
@
$el
.
hasClass
(
"inline-discussion"
)
if
not
@
$
(
".wmd-panel"
).
length
$input
.
bind
'focus'
,
(
e
)
=>
view
=
{
discussion_id
:
@
model
.
id
}
@
$el
.
children
(
".discussion-non-content"
).
append
Mustache
.
render
DiscussionUtil
.
getTemplate
(
"_new_post"
),
view
$newPostBody
=
@
$
(
".new-post-body"
)
DiscussionUtil
.
makeWmdEditor
@
$el
,
$
.
proxy
(
@
$
,
@
),
"new-post-body"
$input
=
DiscussionUtil
.
getWmdInput
@
$el
,
$
.
proxy
(
@
$
,
@
),
"new-post-body"
$input
.
attr
(
"placeholder"
,
"post a new topic..."
)
if
@
$el
.
hasClass
(
"inline-discussion"
)
$input
.
bind
'focus'
,
(
e
)
=>
@
$
(
".new-post-form"
).
removeClass
(
'collapsed'
)
else
if
@
$el
.
hasClass
(
"forum-discussion"
)
@
$
(
".new-post-form"
).
removeClass
(
'collapsed'
)
@
$
(
".new-post-form"
).
removeClass
(
'collapsed'
)
else
if
@
$el
.
hasClass
(
"forum-discussion"
)
@
$
(
".new-post-form"
).
removeClass
(
'collapsed'
)
@
$
(
".new-post-tags"
).
tagsInput
DiscussionUtil
.
tagsInputOptions
()
@
$
(
".new-post-tags"
).
tagsInput
DiscussionUtil
.
tagsInputOptions
()
@
$
(
".new-post-title"
).
blur
$
.
proxy
(
@
loadSimilarPost
,
@
)
@
$
(
".new-post-title"
).
blur
$
.
proxy
(
@
loadSimilarPost
,
@
)
@
$
(
".hide-similar-posts"
).
click
=>
@
$
(
".new-post-similar-posts-wrapper"
).
hide
()
@
$
(
".hide-similar-posts"
).
click
=>
@
$
(
".new-post-similar-posts-wrapper"
).
hide
()
@
$
(
".discussion-submit-post"
).
click
$
.
proxy
(
@
submitNewPost
,
@
)
@
$
(
".discussion-cancel-post"
).
click
$
.
proxy
(
@
cancelNewPost
,
@
)
@
$
(
".discussion-submit-post"
).
click
$
.
proxy
(
@
submitNewPost
,
@
)
@
$
(
".discussion-cancel-post"
).
click
$
.
proxy
(
@
cancelNewPost
,
@
)
@
$
(
".new-post-form"
).
show
()
submitNewPost
:
(
event
)
->
title
=
@
$
(
".new-post-title"
).
val
()
body
=
DiscussionUtil
.
getWmdContent
@
$el
,
$
.
proxy
(
@
$
,
@
),
"new-post-body"
tags
=
@
$
(
".new-post-tags"
).
val
()
anonymous
=
false
||
@
$
(
".discussion-post-anonymously"
).
is
(
":checked"
)
autowatch
=
false
||
@
$
(
".discussion-auto-watch"
).
is
(
":checked"
)
url
=
DiscussionUtil
.
urlFor
(
'create_thread'
,
@
model
.
id
)
DiscussionUtil
.
safeAjax
$elem
:
$
(
event
.
target
)
url
:
url
type
:
"POST"
dataType
:
'json'
data
:
title
:
title
body
:
body
tags
:
tags
anonymous
:
anonymous
auto_subscribe
:
autowatch
error
:
DiscussionUtil
.
formErrorHandler
(
@
$
(
".new-post-form-errors"
))
success
:
(
response
,
textStatus
)
=>
DiscussionUtil
.
clearFormErrors
(
@
$
(
".new-post-form-errors"
))
$thread
=
$
(
response
.
html
)
@
$el
.
children
(
".threads"
).
prepend
(
$thread
)
@
$
(
".new-post-title"
).
val
(
""
)
DiscussionUtil
.
setWmdContent
@
$el
,
$
.
proxy
(
@
$
,
@
),
"new-post-body"
,
""
@
$
(
".new-post-tags"
).
val
(
""
)
@
$
(
".new-post-tags"
).
importTags
(
""
)
thread
=
@
model
.
addThread
response
.
content
threadView
=
new
ThreadView
el
:
$thread
[
0
],
model
:
thread
thread
.
updateInfo
response
.
annotated_content_info
@
cancelNewPost
()
cancelNewPost
:
(
event
)
->
@
$
(
".new-post-form"
).
show
()
if
@
$el
.
hasClass
(
"inline-discussion"
)
@
$
(
".new-post-form"
).
addClass
(
"collapsed"
)
submitNewPost
:
(
event
)
->
else
if
@
$el
.
hasClass
(
"forum-discussion"
)
title
=
@
$
(
".new-post-title"
).
val
()
@
$
(
".new-post-form"
).
hide
()
body
=
DiscussionUtil
.
getWmdContent
@
$el
,
$
.
proxy
(
@
$
,
@
),
"new-post-body"
tags
=
@
$
(
".new-post-tags"
).
val
()
search
:
(
event
)
->
anonymous
=
false
||
@
$
(
".discussion-post-anonymously"
).
is
(
":checked"
)
event
.
preventDefault
()
autowatch
=
false
||
@
$
(
".discussion-auto-watch"
).
is
(
":checked"
)
$elem
=
$
(
event
.
target
)
url
=
DiscussionUtil
.
urlFor
(
'create_thread'
,
@
model
.
id
)
url
=
URI
(
$elem
.
attr
(
"action"
)).
addSearch
({
text
:
@
$
(
".search-input"
).
val
()})
DiscussionUtil
.
safeAjax
@
reload
(
$elem
,
url
)
$elem
:
$
(
event
.
target
)
$loading
:
$
(
event
.
target
)
if
event
sort
:
->
url
:
url
$elem
=
$
(
event
.
target
)
type
:
"POST"
url
=
$elem
.
attr
(
"sort-url"
)
dataType
:
'json'
@
reload
(
$elem
,
url
)
data
:
title
:
title
page
:
(
event
)
->
body
:
body
$elem
=
$
(
event
.
target
)
tags
:
tags
url
=
$elem
.
attr
(
"page-url"
)
anonymous
:
anonymous
@
reload
(
$elem
,
url
)
auto_subscribe
:
autowatch
error
:
DiscussionUtil
.
formErrorHandler
(
@
$
(
".new-post-form-errors"
))
events
:
success
:
(
response
,
textStatus
)
=>
"submit .search-wrapper>.discussion-search-form"
:
"search"
DiscussionUtil
.
clearFormErrors
(
@
$
(
".new-post-form-errors"
))
"click .discussion-search-link"
:
"search"
$thread
=
$
(
response
.
html
)
"click .discussion-sort-link"
:
"sort"
@
$el
.
children
(
".threads"
).
prepend
(
$thread
)
"click .discussion-page-link"
:
"page"
@
$
(
".new-post-similar-posts"
).
empty
()
@
$
(
".new-post-similar-posts-wrapper"
).
hide
()
@
$
(
".new-post-title"
).
val
(
""
).
attr
(
"prev-text"
,
""
)
DiscussionUtil
.
setWmdContent
@
$el
,
$
.
proxy
(
@
$
,
@
),
"new-post-body"
,
""
@
$
(
".new-post-tags"
).
val
(
""
)
@
$
(
".new-post-tags"
).
importTags
(
""
)
thread
=
@
model
.
addThread
response
.
content
threadView
=
new
ThreadView
el
:
$thread
[
0
],
model
:
thread
thread
.
updateInfo
response
.
annotated_content_info
@
cancelNewPost
()
cancelNewPost
:
(
event
)
->
if
@
$el
.
hasClass
(
"inline-discussion"
)
@
$
(
".new-post-form"
).
addClass
(
"collapsed"
)
else
if
@
$el
.
hasClass
(
"forum-discussion"
)
@
$
(
".new-post-form"
).
hide
()
search
:
(
event
)
->
event
.
preventDefault
()
$elem
=
$
(
event
.
target
)
url
=
URI
(
$elem
.
attr
(
"action"
)).
addSearch
({
text
:
@
$
(
".search-input"
).
val
()})
@
reload
(
$elem
,
url
)
sort
:
->
$elem
=
$
(
event
.
target
)
url
=
$elem
.
attr
(
"sort-url"
)
@
reload
(
$elem
,
url
)
page
:
(
event
)
->
$elem
=
$
(
event
.
target
)
url
=
$elem
.
attr
(
"page-url"
)
@
reload
(
$elem
,
url
)
events
:
"submit .search-wrapper>.discussion-search-form"
:
"search"
"click .discussion-search-link"
:
"search"
"click .discussion-sort-link"
:
"sort"
"click .discussion-page-link"
:
"page"
lms/static/coffee/src/discussion/discussion_module.coffee
View file @
f0737c18
class
@
DiscussionModuleView
extends
Backbone
.
View
if
Backbone
?
events
:
class
@
DiscussionModuleView
extends
Backbone
.
View
"click .discussion-show"
:
"toggleDiscussion"
events
:
toggleDiscussion
:
(
event
)
->
"click .discussion-show"
:
"toggleDiscussion"
if
@
showed
toggleDiscussion
:
(
event
)
->
@
$
(
"section.discussion"
).
hide
()
if
@
showed
$
(
event
.
target
).
html
(
"Show Discussion"
)
@
$
(
"section.discussion"
).
hide
()
@
showed
=
false
$
(
event
.
target
).
html
(
"Show Discussion"
)
else
@
showed
=
false
if
@
retrieved
@
$
(
"section.discussion"
).
show
()
$
(
event
.
target
).
html
(
"Hide Discussion"
)
@
showed
=
true
else
else
$elem
=
$
(
event
.
target
)
if
@
retrieved
discussion_id
=
$elem
.
attr
(
"discussion_id"
)
@
$
(
"section.discussion"
).
show
()
url
=
DiscussionUtil
.
urlFor
'retrieve_discussion'
,
discussion_id
$
(
event
.
target
).
html
(
"Hide Discussion"
)
Discussion
.
safeAjax
@
showed
=
true
$elem
:
$elem
else
url
:
url
$elem
=
$
(
event
.
target
)
type
:
"GET"
discussion_id
=
$elem
.
attr
(
"discussion_id"
)
dataType
:
'json'
url
=
DiscussionUtil
.
urlFor
'retrieve_discussion'
,
discussion_id
success
:
(
response
,
textStatus
)
=>
DiscussionUtil
.
safeAjax
@
$el
.
append
(
response
.
html
)
$elem
:
$elem
$discussion
=
@
$el
.
find
(
"section.discussion"
)
$loading
:
$elem
$
(
event
.
target
).
html
(
"Hide Discussion"
)
url
:
url
discussion
=
new
Discussion
()
type
:
"GET"
discussion
.
reset
(
response
.
discussionData
,
{
silent
:
false
})
dataType
:
'json'
view
=
new
DiscussionView
(
el
:
$discussion
[
0
],
model
:
discussion
)
success
:
(
response
,
textStatus
)
=>
DiscussionUtil
.
bulkUpdateContentInfo
(
window
.
$
$annotated_content_info
)
@
$el
.
append
(
response
.
html
)
@
retrieved
=
true
$discussion
=
@
$el
.
find
(
"section.discussion"
)
@
showed
=
true
$
(
event
.
target
).
html
(
"Hide Discussion"
)
discussion
=
new
Discussion
()
discussion
.
reset
(
response
.
discussionData
,
{
silent
:
false
})
view
=
new
DiscussionView
(
el
:
$discussion
[
0
],
model
:
discussion
)
DiscussionUtil
.
bulkUpdateContentInfo
(
window
.
$
$annotated_content_info
)
@
retrieved
=
true
@
showed
=
true
lms/static/coffee/src/discussion/main.coffee
View file @
f0737c18
...
@@ -12,4 +12,10 @@ $ ->
...
@@ -12,4 +12,10 @@ $ ->
discussion
.
reset
(
discussionData
,
{
silent
:
false
})
discussion
.
reset
(
discussionData
,
{
silent
:
false
})
view
=
new
DiscussionView
(
el
:
elem
,
model
:
discussion
)
view
=
new
DiscussionView
(
el
:
elem
,
model
:
discussion
)
DiscussionUtil
.
bulkUpdateContentInfo
(
window
.
$
$annotated_content_info
)
if
window
.
$
$annotated_content_info
?
DiscussionUtil
.
bulkUpdateContentInfo
(
window
.
$
$annotated_content_info
)
$userProfile
=
$
(
".discussion-sidebar>.user-profile"
)
if
$userProfile
.
length
console
.
log
"initialize user profile"
view
=
new
DiscussionUserProfileView
(
el
:
$userProfile
[
0
])
lms/static/coffee/src/discussion/user_profile.coffee
View file @
f0737c18
if
not
@
Discussion
?
class
@
DiscussionUserProfileView
extends
Backbone
.
View
@
Discussion
=
{}
toggleModeratorStatus
:
(
event
)
->
confirmValue
=
confirm
(
"Are you sure?"
)
if
not
confirmValue
then
return
$elem
=
$
(
event
.
target
)
if
$elem
.
hasClass
(
"sidebar-promote-moderator-button"
)
isModerator
=
true
else
if
$elem
.
hasClass
(
"sidebar-revoke-moderator-button"
)
isModerator
=
false
else
console
.
error
"unrecognized moderator status"
return
url
=
DiscussionUtil
.
urlFor
(
'update_moderator_status'
,
$$profiled_user_id
)
DiscussionUtil
.
safeAjax
$elem
:
$elem
url
:
url
type
:
"POST"
dataType
:
'json'
data
:
is_moderator
:
isModerator
error
:
(
response
,
textStatus
,
e
)
->
console
.
log
e
success
:
(
response
,
textStatus
)
=>
parent
=
@
$el
.
parent
()
@
$el
.
replaceWith
(
response
.
html
)
view
=
new
DiscussionUserProfileView
el
:
parent
.
children
(
".user-profile"
)
Discussion
=
@
Discussion
events
:
"click .sidebar-toggle-moderator-button"
:
"toggleModeratorStatus"
@
Discussion
=
$
.
extend
@
Discussion
,
initializeUserProfile
:
(
$userProfile
)
->
$local
=
Discussion
.
generateLocal
$userProfile
handleUpdateModeratorStatus
=
(
elem
,
isModerator
)
->
confirmValue
=
confirm
(
"Are you sure?"
)
if
not
confirmValue
then
return
url
=
Discussion
.
urlFor
(
'update_moderator_status'
,
$$profiled_user_id
)
Discussion
.
safeAjax
$elem
:
$
(
elem
)
url
:
url
type
:
"POST"
dataType
:
'json'
data
:
is_moderator
:
isModerator
error
:
(
response
,
textStatus
,
e
)
->
console
.
log
e
success
:
(
response
,
textStatus
)
->
parent
=
$userProfile
.
parent
()
$userProfile
.
replaceWith
(
response
.
html
)
Discussion
.
initializeUserProfile
parent
.
children
(
".user-profile"
)
Discussion
.
bindLocalEvents
$local
,
"click .sidebar-revoke-moderator-button"
:
(
event
)
->
handleUpdateModeratorStatus
(
this
,
false
)
"click .sidebar-promote-moderator-button"
:
(
event
)
->
handleUpdateModeratorStatus
(
this
,
true
)
initializeUserActiveDiscussion
:
(
$discussion
)
->
lms/static/coffee/src/discussion/utils.coffee
View file @
f0737c18
$
->
$
.
fn
.
extend
loading
:
->
$
(
this
).
after
(
"<span class='discussion-loading'></span>"
)
loaded
:
->
$
(
this
).
parent
().
children
(
".discussion-loading"
).
remove
()
class
@
DiscussionUtil
class
@
DiscussionUtil
@
wmdEditors
:
{}
@
wmdEditors
:
{}
...
@@ -62,9 +69,16 @@ class @DiscussionUtil
...
@@ -62,9 +69,16 @@ class @DiscussionUtil
$elem
=
params
.
$elem
$elem
=
params
.
$elem
if
$elem
.
attr
(
"disabled"
)
if
$elem
.
attr
(
"disabled"
)
return
return
$elem
.
attr
(
"disabled"
,
"disabled"
)
params
[
"beforeSend"
]
=
->
$elem
.
attr
(
"disabled"
,
"disabled"
)
if
params
[
"$loading"
]
console
.
log
"loading"
params
[
"$loading"
].
loading
()
$
.
ajax
(
params
).
always
->
$
.
ajax
(
params
).
always
->
$elem
.
removeAttr
(
"disabled"
)
$elem
.
removeAttr
(
"disabled"
)
if
params
[
"$loading"
]
console
.
log
"loaded"
params
[
"$loading"
].
loaded
()
@
get
:
(
$elem
,
url
,
data
,
success
)
->
@
get
:
(
$elem
,
url
,
data
,
success
)
->
@
safeAjax
@
safeAjax
...
...
lms/static/images/discussion/loading.gif
0 → 100644
View file @
f0737c18
809 Bytes
lms/static/sass/_discussion.scss
View file @
f0737c18
...
@@ -35,7 +35,13 @@ $tag-text-color: #5b614f;
...
@@ -35,7 +35,13 @@ $tag-text-color: #5b614f;
}
}
}
}
.discussion-loading
{
background-image
:
url(../images/discussion/loading.gif)
;
width
:
15px
;
height
:
15px
;
margin-left
:
2px
;
display
:
inline-block
;
}
/*** Discussions ***/
/*** Discussions ***/
...
@@ -49,8 +55,6 @@ $tag-text-color: #5b614f;
...
@@ -49,8 +55,6 @@ $tag-text-color: #5b614f;
margin-top
:
0
;
margin-top
:
0
;
}
}
/*** Sidebar ***/
/*** Sidebar ***/
.sidebar-module
{
.sidebar-module
{
...
...
lms/static/sass/course.scss
View file @
f0737c18
...
@@ -21,6 +21,12 @@
...
@@ -21,6 +21,12 @@
@import
'course/courseware/sidebar'
;
@import
'course/courseware/sidebar'
;
@import
'course/courseware/amplifier'
;
@import
'course/courseware/amplifier'
;
// course-specific courseware (all styles in these files should be gated by a
// course-specific class). This should be replaced with a better way of
// providing course-specific styling.
@import
"course/courseware/courses/_cs188.scss"
;
// wiki
// wiki
@import
"course/wiki/basic-html"
;
@import
"course/wiki/basic-html"
;
@import
"course/wiki/sidebar"
;
@import
"course/wiki/sidebar"
;
...
...
lms/static/sass/course/courseware/courses/_cs188.scss
0 → 100644
View file @
f0737c18
body
.cs188
{
.course-content
{
.project
{
ul
,
ol
{
margin-top
:
3px
;
list-style
:
disc
;
ul
,
ol
{
margin
:
0px
;
}
}
}
h3
,
h4
{
font-weight
:
bold
;
a
{
color
:
inherit
;
}
}
h4
{
font-size
:
1em
;
}
p
,
.code_snippet
{
margin-bottom
:
1
.416em
;
}
}
}
lms/templates/courseware/courseware.html
View file @
f0737c18
...
@@ -22,6 +22,7 @@
...
@@ -22,6 +22,7 @@
##
<script
type=
"text/javascript"
src=
"${static.url('js/vendor/CodeMirror-2.25/mode/python/python.js')}"
></script>
##
<script
type=
"text/javascript"
src=
"${static.url('js/vendor/CodeMirror-2.25/mode/python/python.js')}"
></script>
<
%
static:js
group=
'courseware'
/>
<
%
static:js
group=
'courseware'
/>
<
%
static:js
group=
'discussion'
/>
<
%
include
file=
"../discussion/_js_body_dependencies.html"
/>
<
%
include
file=
"../discussion/_js_body_dependencies.html"
/>
...
...
lms/templates/discussion/_content_renderer.html
View file @
f0737c18
<
%!
import
django_comment_client
.
helpers
as
helpers
%
>
<
%!
import
django_comment_client
.
helpers
as
helpers
%
>
<
%
def
name=
"render_content(content)"
>
<
%
def
name=
"render_content(content
, *args, **kwargs
)"
>
${helpers.render_content(content)}
${helpers.render_content(content
, *args, **kwargs
)}
</
%
def>
</
%
def>
<
%
def
name=
"render_content_with_comments(content)"
>
<
%
def
name=
"render_content_with_comments(content
, *args, **kwargs
)"
>
<div
class=
"${content['type']}${helpers.show_if(' endorsed', content.get('endorsed'))}"
_id=
"${content['id']}"
_discussion_id=
"${content.get('commentable_id', '')}"
_author_id=
"${helpers.show_if(content['user_id'], not content.get('anonymous'))}"
>
<div
class=
"${content['type']}${helpers.show_if(' endorsed', content.get('endorsed'))}"
_id=
"${content['id']}"
_discussion_id=
"${content.get('commentable_id', '')}"
_author_id=
"${helpers.show_if(content['user_id'], not content.get('anonymous'))}"
>
${render_content(content)}
${render_content(content
, *args, **kwargs
)}
${render_comments(content.get('children', []))}
${render_comments(content.get('children', [])
, *args, **kwargs
)}
</div>
</div>
</
%
def>
</
%
def>
<
%
def
name=
"render_comments(comments)"
>
<
%
def
name=
"render_comments(comments
, *args, **kwargs
)"
>
<div
class=
"comments"
>
<div
class=
"comments"
>
% for comment in comments:
% for comment in comments:
${render_content_with_comments(comment)}
${render_content_with_comments(comment
, *args, **kwargs
)}
% endfor
% endfor
</div>
</div>
</
%
def>
</
%
def>
lms/templates/discussion/_similar_posts.html
0 → 100644
View file @
f0737c18
% if len(threads) > 0:
Similar Posts:
<a
class=
"hide-similar-posts"
href=
"javascript:void(0)"
>
Hide
</a>
<div
class=
"new-post-similar-posts"
>
% for thread in threads:
<a
class=
"similar-post"
href=
"${thread['permalink']}"
>
${thread['title']}
</a>
% endfor
</div>
% endif
lms/templates/discussion/_user_active_threads.html
View file @
f0737c18
<
%
namespace
name=
"renderer"
file=
"_
thread
.html"
/>
<
%
namespace
name=
"renderer"
file=
"_
content_renderer
.html"
/>
<section
class=
"discussion user-active-discussion"
>
<section
class=
"discussion user-active-discussion"
_id=
"${user_id}"
>
<div
class=
"discussion-non-content
discussion-
local"
></div>
<div
class=
"discussion-non-content local"
></div>
<div
class=
"threads"
>
<div
class=
"threads"
>
% for thread in threads:
% for thread in threads:
${renderer.render_
thread(course_id, thread, show_comments=True
)}
${renderer.render_
content_with_comments(thread, {'partial_comments': True}
)}
% endfor
% endfor
</div>
</div>
...
...
lms/templates/discussion/_user_profile.html
View file @
f0737c18
<
%!
from
django_comment_client
.
util
s
import
pluralize
%
>
<
%!
from
django_comment_client
.
helper
s
import
pluralize
%
>
<
%!
from
django_comment_client
.
permissions
import
has_permission
,
check_permissions_by_view
%
>
<
%!
from
django_comment_client
.
permissions
import
has_permission
,
check_permissions_by_view
%
>
<
%!
from
operator
import
attrgetter
%
>
<
%!
from
operator
import
attrgetter
%
>
...
@@ -15,9 +15,9 @@
...
@@ -15,9 +15,9 @@
<div
class=
"sidebar-comments-count"
><span>
${profiled_user['comments_count']}
</span>
${pluralize('comment', profiled_user['comments_count'])}
</div>
<div
class=
"sidebar-comments-count"
><span>
${profiled_user['comments_count']}
</span>
${pluralize('comment', profiled_user['comments_count'])}
</div>
% if check_permissions_by_view(user, course.id, content=None, name='update_moderator_status'):
% if check_permissions_by_view(user, course.id, content=None, name='update_moderator_status'):
% if "Moderator" in role_names:
% if "Moderator" in role_names:
<a
href=
"javascript:void(0)"
class=
"sidebar-revoke-moderator-button"
>
Revoke Moderator provileges
</a>
<a
href=
"javascript:void(0)"
class=
"sidebar-
toggle-moderator-button sidebar-
revoke-moderator-button"
>
Revoke Moderator provileges
</a>
% else:
% else:
<a
href=
"javascript:void(0)"
class=
"sidebar-promote-moderator-button"
>
Promote to Moderator
</a>
<a
href=
"javascript:void(0)"
class=
"sidebar-
toggle-moderator-button sidebar-
promote-moderator-button"
>
Promote to Moderator
</a>
% endif
% endif
% endif
% endif
</div>
</div>
lms/templates/discussion/index.html
View file @
f0737c18
<
%
inherit
file=
"../main.html"
/>
<
%
inherit
file=
"../main.html"
/>
<
%
namespace
name=
'static'
file=
'../static_content.html'
/>
<
%
namespace
name=
'static'
file=
'../static_content.html'
/>
<
%
block
name=
"bodyclass"
>
discussion
</
%
block>
<
%
block
name=
"bodyclass"
>
discussion
</
%
block>
<
%
block
name=
"title"
><title>
Discussion –
MITx 6.002x
</title></
%
block>
<
%
block
name=
"title"
><title>
Discussion –
${course.number}
</title></
%
block>
<
%
block
name=
"headextra"
>
<
%
block
name=
"headextra"
>
<
%
static:css
group=
'course'
/>
<
%
static:css
group=
'course'
/>
...
@@ -32,7 +32,7 @@
...
@@ -32,7 +32,7 @@
</section>
</section>
<section
class=
"course-content"
>
<section
class=
"course-content"
>
${content}
${content
.decode('utf-8')
}
</section>
</section>
</div>
</div>
</section>
</section>
lms/templates/discussion/mustache/_content.mustache
View file @
f0737c18
...
@@ -37,7 +37,7 @@
...
@@ -37,7 +37,7 @@
anonymous
anonymous
{{/
content
.
anonymous
}}
{{/
content
.
anonymous
}}
{{^
content
.
anonymous
}}
{{^
content
.
anonymous
}}
{{
content
.
username
}}
<a
href=
"
{{#
#
url_for_user
}}{{
content
.
user_id
}}{{/
url_for_user
}}
"
>
{{
content
.
username
}}
</a>
{{/
content
.
anonymous
}}
{{/
content
.
anonymous
}}
</div>
</div>
<div
class=
"show-comments-wrapper"
>
<div
class=
"show-comments-wrapper"
>
...
@@ -51,7 +51,9 @@
...
@@ -51,7 +51,9 @@
{{/
thread
}}
{{/
thread
}}
</div>
</div>
<ul
class=
"discussion-actions"
>
<ul
class=
"discussion-actions"
>
<li><a
class=
"discussion-link discussion-reply discussion-reply-
{{
content
.
type
}}
"
href=
"javascript:void(0)"
>
Reply
</a></li>
{{^
max_depth
}}
<li><a
class=
"discussion-link discussion-reply discussion-reply-
{{
content
.
type
}}
"
href=
"javascript:void(0)"
>
Reply
</a></li>
{{/
max_depth
}}
{{#
thread
}}
{{#
thread
}}
<li><div
class=
"follow-wrapper"
><a
class=
"discussion-link discussion-follow-thread"
href=
"javascript:void(0)"
>
Follow
</a></div></li>
<li><div
class=
"follow-wrapper"
><a
class=
"discussion-link discussion-follow-thread"
href=
"javascript:void(0)"
>
Follow
</a></div></li>
{{/
thread
}}
{{/
thread
}}
...
...
lms/templates/discussion/mustache/_new_post.mustache
View file @
f0737c18
<form
class=
"new-post-form collapsed"
id=
"new-post-form"
style=
"display: block; "
>
<form
class=
"new-post-form collapsed"
id=
"new-post-form"
style=
"display: block; "
>
<ul
class=
"new-post-form-errors discussion-errors"
></ul>
<ul
class=
"new-post-form-errors discussion-errors"
></ul>
<input
type=
"text"
class=
"new-post-title title-input"
placeholder=
"Title"
/>
<input
type=
"text"
class=
"new-post-title title-input"
placeholder=
"Title"
/>
<div
class=
"new-post-similar-posts-wrapper"
style=
"display: none"
>
<div
class=
"new-post-similar-posts-wrapper"
style=
"display: none"
></div>
Similar Posts:
<a
class=
"hide-similar-posts"
href=
"javascript:void(0)"
>
Hide
</a>
<div
class=
"new-post-similar-posts"
></div>
</div>
<div
class=
"new-post-body reply-body"
></div>
<div
class=
"new-post-body reply-body"
></div>
<input
class=
"new-post-tags"
placeholder=
"Tags"
/>
<input
class=
"new-post-tags"
placeholder=
"Tags"
/>
<div
class=
"post-options"
>
<div
class=
"post-options"
>
...
...
lms/templates/discussion/single_thread.html
View file @
f0737c18
<
%
inherit
file=
"../main.html"
/>
<
%
inherit
file=
"../main.html"
/>
<
%
namespace
name=
'static'
file=
'../static_content.html'
/>
<
%
namespace
name=
'static'
file=
'../static_content.html'
/>
<
%
block
name=
"bodyclass"
>
discussion
</
%
block>
<
%
block
name=
"bodyclass"
>
discussion
</
%
block>
<
%
block
name=
"title"
><title>
Discussion –
MITx 6.002x
</title></
%
block>
<
%
block
name=
"title"
><title>
Discussion –
${course.number}
</title></
%
block>
<
%
block
name=
"headextra"
>
<
%
block
name=
"headextra"
>
<
%
static:css
group=
'course'
/>
<
%
static:css
group=
'course'
/>
...
@@ -30,7 +30,7 @@
...
@@ -30,7 +30,7 @@
</section>
</section>
<section
class=
"course-content"
>
<section
class=
"course-content"
>
${content}
${content
.decode('utf-8')
}
</section>
</section>
</div>
</div>
</section>
</section>
lms/templates/discussion/user_profile.html
View file @
f0737c18
<
%!
from
django
.
template
.
defaultfilters
import
escapejs
%
>
<
%!
from
django
.
template
.
defaultfilters
import
escapejs
%
>
<
%
namespace
name=
"renderer"
file=
"_thread.html"
/>
<
%
inherit
file=
"../main.html"
/>
<
%
inherit
file=
"../main.html"
/>
<
%
namespace
name=
'static'
file=
'../static_content.html'
/>
<
%
namespace
name=
'static'
file=
'../static_content.html'
/>
<
%
block
name=
"bodyclass"
>
discussion
</
%
block>
<
%
block
name=
"bodyclass"
>
discussion
</
%
block>
<
%
block
name=
"title"
><title>
Discussion –
MITx 6.002x
</title></
%
block>
<
%
block
name=
"title"
><title>
Discussion –
${course.number}
</title></
%
block>
<
%
block
name=
"headextra"
>
<
%
block
name=
"headextra"
>
<
%
static:css
group=
'course'
/>
<
%
static:css
group=
'course'
/>
<
%
include
file=
"_js_head_dependencies.html"
/>
</
%
block>
</
%
block>
<
%
block
name=
"js_extra"
>
<
%
block
name=
"js_extra"
>
<
%
include
file=
"_js_dependencies.html"
/>
<
%
include
file=
"_js_body_dependencies.html"
/>
<
%
static:js
group=
'discussion'
/>
</
%
block>
</
%
block>
<
%
include
file=
"/courseware/course_navigation.html"
args=
"active_page='discussion'"
/>
<
%
include
file=
"
..
/courseware/course_navigation.html"
args=
"active_page='discussion'"
/>
<section
class=
"container"
>
<section
class=
"container"
>
<div
class=
"course-wrapper"
>
<div
class=
"course-wrapper"
>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment