diff --git a/:w b/:w new file mode 100644 index 0000000000..f433df211c --- /dev/null +++ b/:w @@ -0,0 +1,453 @@ +if Backbone? + class @Content extends Backbone.Model + + template: -> DiscussionUtil.getTemplate('_content') + + actions: + editable: '.admin-edit' + can_reply: '.discussion-reply' + can_endorse: '.admin-endorse' + can_delete: '.admin-delete' + can_openclose: '.admin-openclose' + + urlMappers: {} + + urlFor: (name) -> + @urlMappers[name].apply(@) + + can: (action) -> + DiscussionUtil.getContentInfo @id, action + + updateInfo: (info) -> + @set('ability', info.ability) + @set('voted', info.voted) + @set('subscribed', info.subscribed) + + addComment: (comment, options) -> + options ||= {} + 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') + 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) -> + @$(".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().hide() + else + @$(elemSelector).parent().show() + + $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() + + showSingleThread: (event) -> + if @retrieved() + @$el.children(".comments").show() + @showed = true + @updateShowComments() + else + $elem = $.merge @$(".thread-title"), @$showComments() + url = @model.urlFor('retrieve') + DiscussionUtil.safeAjax + $elem: $elem + $loading: @$(".discussion-show-comments") + type: "GET" + url: url + success: (response, textStatus) => + @showed = true + @updateShowComments() + @$showComments().addClass("retrieved") + @$el.children(".comments").replaceWith response.html + @model.resetComments response.content.children + @initCommentViews() + DiscussionUtil.bulkUpdateContentInfo response.annotated_content_info + + toggleSingleThread: (event) -> + if @showed + @hideSingleThread(event) + else + @showSingleThread(event) + + initCommentViews: -> + @$el.children(".comments").children(".comment").each (index, elem) => + model = @model.get('comments').find $(elem).attr("_id") + if not model.view + commentView = new CommentView el: elem, model: model + + reply: -> + if @model.get('type') == 'thread' + @showSingleThread() + $replyView = @$(".discussion-reply-new") + if $replyView.length + $replyView.show() + else + view = {} + view.id = @model.id + view.showWatchCheckbox = not @model.get('thread').get('subscribed') + html = Mustache.render DiscussionUtil.getTemplate('_reply'), view + @$discussionContent().append html + DiscussionUtil.makeWmdEditor @$el, $.proxy(@$, @), "reply-body" + @$(".discussion-submit-post").click $.proxy(@submitReply, @) + @$(".discussion-cancel-post").click $.proxy(@cancelReply, @) + @$(".discussion-reply").hide() + @$(".discussion-edit").hide() + + submitReply: (event) -> + url = @model.urlFor('reply') + + body = DiscussionUtil.getWmdContent @$el, $.proxy(@$, @), "reply-body" + + anonymous = false || @$(".discussion-post-anonymously").is(":checked") + autowatch = false || @$(".discussion-auto-watch").is(":checked") + + DiscussionUtil.safeAjax + $elem: $(event.target) + $loading: $(event.target) if event + url: url + type: "POST" + dataType: 'json' + data: + body: body + anonymous: anonymous + auto_subscribe: autowatch + error: DiscussionUtil.formErrorHandler @$(".discussion-errors") + success: (response, textStatus) => + DiscussionUtil.clearFormErrors @$(".discussion-errors") + $comment = $(response.html) + @$el.children(".comments").prepend $comment + DiscussionUtil.setWmdContent @$el, $.proxy(@$, @), "reply-body", "" + comment = @model.addComment response.content + commentView = new CommentView el: $comment[0], model: comment + comment.updateInfo response.annotated_content_info + if autowatch + @model.get('thread').set('subscribed', true) + @cancelReply() + + cancelReply: -> + $replyView = @$(".discussion-reply-new") + if $replyView.length + $replyView.hide() + @$(".discussion-reply").show() + @$(".discussion-edit").show() + + unvote: (event) -> + url = @model.urlFor('unvote') + $elem = @$(".discussion-vote") + DiscussionUtil.safeAjax + $elem: $elem + url: url + type: "POST" + success: (response, textStatus) => + @model.set('voted', '') + @model.set('votes_point', response.votes.point) + + vote: (event, value) -> + url = @model.urlFor("#{value}vote") + $elem = @$(".discussion-vote") + DiscussionUtil.safeAjax + $elem: $elem + url: url + type: "POST" + success: (response, textStatus) => + @model.set('voted', value) + @model.set('votes_point', response.votes.point) + + toggleVote: (event) -> + console.log("HERE") + $elem = $(event.target) + value = $elem.attr("value") + $elem.toggleClass("is-cast") + return false + # if @model.get("voted") == value + # @unvote(event) + # else + # @vote(event, value) + + toggleEndorse: (event) -> + $elem = $(event.target) + url = @model.urlFor('endorse') + endorsed = @model.get('endorsed') + data = { endorsed: not endorsed } + DiscussionUtil.safeAjax + $elem: $elem + url: url + data: data + type: "POST" + success: (response, textStatus) => + @model.set('endorsed', not endorsed) + + 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) + @model.set('ability', response.ability) + + 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 = @model.get('title') + view.body = @model.get('body') + view.tags = @model.get('tags') + else + view.body = @model.get('body') + @$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) + if @model.get('type') == 'thread' + @model = new Thread response.content + else + @model = new Comment $.extend {}, response.content, { thread: @model.get('thread') } + @reconstruct() + @model.updateInfo response.annotated_content_info, { forceUpdate: true } + + cancelEdit: (event) -> + @$(".discussion-content-edit").hide() + @$(".discussion-content-wrapper").show() + + delete: (event) -> + url = @model.urlFor('delete') + if @model.get('type') == 'thread' + c = confirm "Are you sure to delete thread \"#{@model.get('title')}\"?" + else + c = confirm "Are you sure to delete this comment? " + if not c + return + $elem = $(event.target) + DiscussionUtil.safeAjax + $elem: $elem + url: url + type: "POST" + success: (response, textStatus) => + @$el.remove() + if @model.get('type') == 'comment' + @model.get('thread').removeComment(@model) + + events: + "click .discussion-follow-thread": "toggleFollow" + "click .thread-title": "toggleSingleThread" + "click .discussion-show-comments": "toggleSingleThread" + "click .discussion-reply-thread": "reply" + "click .discussion-reply-comment": "reply" + "click .discussion-cancel-reply": "cancelReply" + "click .discussion-vote-up": "toggleVote" + "click .discussion-vote-down": "toggleVote" + "click .admin-endorse": "toggleEndorse" + "click .admin-openclose": "toggleClosed" + "click .admin-edit": "edit" + "click .admin-delete": "delete" + + initLocal: -> + @$local = @$el.children(".local") + @$delegateElement = @$local + + initTitle: -> + $contentTitle = @$(".thread-title") + if $contentTitle.length + $contentTitle.html DiscussionUtil.unescapeHighlightTag DiscussionUtil.stripLatexHighlight $contentTitle.html() + + initBody: -> + $contentBody = @$(".content-body") + $contentBody.html DiscussionUtil.postMathJaxProcessor DiscussionUtil.markdownWithHighlight $contentBody.html() + MathJax.Hub.Queue ["Typeset", MathJax.Hub, $contentBody.attr("id")] + + initTimeago: -> + @$("span.timeago").timeago() + + renderPartial: -> + for attr, value of @model.changedAttributes() + if @partial[attr] + @partial[attr].apply(@, [value]) + + initBindings: -> + @model.view = @ + @model.bind('change', @renderPartial, @) + + initialize: -> + @initBindings() + @initLocal() + @initTimeago() + @initTitle() + @initBody() + @initCommentViews() + + reconstruct: -> + @initBindings() + @initLocal() + @initTimeago() + @initTitle() + @initBody() + @delegateEvents() + + 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() + + 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) + + 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) diff --git a/lms/djangoapps/django_comment_client/forum/views.py b/lms/djangoapps/django_comment_client/forum/views.py index 48f130f107..ed09f1cfdb 100644 --- a/lms/djangoapps/django_comment_client/forum/views.py +++ b/lms/djangoapps/django_comment_client/forum/views.py @@ -182,6 +182,7 @@ def render_single_thread(request, discussion_id, course_id, thread_id): annotated_content_info = utils.get_annotated_content_infos(course_id, thread=thread, user=request.user, user_info=user_info) + log.debug(annotated_content_info) context = { 'discussion_id': discussion_id, 'thread': thread, @@ -191,6 +192,7 @@ def render_single_thread(request, discussion_id, course_id, thread_id): 'discussion_data': json.dumps({ discussion_id: [utils.safe_content(thread)] }), 'threads': threads, } + return render_to_string('discussion/_single_thread.html', context) def single_thread(request, course_id, discussion_id, thread_id): @@ -223,10 +225,18 @@ def single_thread(request, course_id, discussion_id, thread_id): course_id, ) + + user_info = cc.User.from_django_user(request.user).to_dict() + thread = cc.Thread.find(thread_id).retrieve(recursive=True) + annotated_content_info = utils.get_annotated_content_infos(course_id, thread=thread, user=request.user, user_info=user_info) + + context = { 'discussion_id': discussion_id, 'csrf': csrf(request)['csrf_token'], 'init': '', + 'thread': json.dumps(utils.safe_content(thread)), + 'annotated_content_info': json.dumps(annotated_content_info), 'content': render_single_thread(request, discussion_id, course_id, thread_id), 'course': course, 'recent_active_threads': recent_active_threads, diff --git a/lms/static/coffee/src/discussion/content.coffee b/lms/static/coffee/src/discussion/content.coffee index 73c3688c2a..f433df211c 100644 --- a/lms/static/coffee/src/discussion/content.coffee +++ b/lms/static/coffee/src/discussion/content.coffee @@ -227,12 +227,15 @@ if Backbone? @model.set('votes_point', response.votes.point) toggleVote: (event) -> + console.log("HERE") $elem = $(event.target) value = $elem.attr("value") - if @model.get("voted") == value - @unvote(event) - else - @vote(event, value) + $elem.toggleClass("is-cast") + return false + # if @model.get("voted") == value + # @unvote(event) + # else + # @vote(event, value) toggleEndorse: (event) -> $elem = $(event.target) diff --git a/lms/static/coffee/src/discussion/main.coffee b/lms/static/coffee/src/discussion/main.coffee index 023345c5da..783ab9a3d5 100644 --- a/lms/static/coffee/src/discussion/main.coffee +++ b/lms/static/coffee/src/discussion/main.coffee @@ -1,21 +1,81 @@ -$ -> +class @DiscussionUser + constructor: (content_info) -> + @content_info = content_info + following: (thread) -> + @content_info[thread.id]['subscribed'] == true + + voted: (thread) -> + @content_info[thread.id]['voted'] == 'up' + +class @DiscussionThreadView extends Backbone.View + events: + "click .discussion-vote-up": "toggleVote" + "click .dogear": "toggleFollowing" + initialize: (options) -> + @user = options['user'] + @model.bind "change", @updateModelDetails + + updateModelDetails: => + @$(".votes-count-number").html(@model.get("votes")["up_count"]) + + render: -> + if @user.following(@model) + @$(".dogear").addClass("is-followed") + + if @user.voted(@model) + @$(".vote-btn").addClass("is-cast") + + toggleVote: -> + @$(".vote-btn").toggleClass("is-cast") + if @$(".vote-btn").hasClass("is-cast") + @vote() + else + @unvote() + + toggleFollowing: -> + @$(".dogear").toggleClass("is-followed") + + vote: -> + url = @model.urlFor("upvote") + @$(".votes-count-number").html(parseInt(@$(".votes-count-number").html()) + 1) + DiscussionUtil.safeAjax + $elem: @$(".discussion-vote") + url: url + type: "POST" + success: (response, textStatus) => + if textStatus == 'success' + @model.set(response) + + unvote: -> + url = @model.urlFor("unvote") + @$(".votes-count-number").html(parseInt(@$(".votes-count-number").html()) - 1) + DiscussionUtil.safeAjax + $elem: @$(".discussion-vote") + url: url + type: "POST" + success: (response, textStatus) => + if textStatus == 'success' + @model.set(response) + +$ -> window.$$contents = {} window.$$discussions = {} - $(".discussion-module").each (index, elem) -> - view = new DiscussionModuleView(el: elem) + # $(".discussion-module").each (index, elem) -> + # view = new DiscussionModuleView(el: elem) - $("section.discussion").each (index, elem) -> - discussionData = DiscussionUtil.getDiscussionData($(elem).attr("_id")) - discussion = new Discussion() - discussion.reset(discussionData, {silent: false}) - view = new DiscussionView(el: elem, model: discussion) + # $("section.discussion").each (index, elem) -> + # discussionData = DiscussionUtil.getDiscussionData($(elem).attr("_id")) + # discussion = new Discussion() + # discussion.reset(discussionData, {silent: false}) + # view = new DiscussionView(el: elem, model: discussion) - if window.$$annotated_content_info? - 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]) - $userProfile = $(".discussion-sidebar>.user-profile") - if $userProfile.length - console.log "initialize user profile" - view = new DiscussionUserProfileView(el: $userProfile[0]) diff --git a/lms/static/images/endorse-icon.png b/lms/static/images/endorse-icon.png new file mode 100644 index 0000000000..4dc5c6e204 Binary files /dev/null and b/lms/static/images/endorse-icon.png differ diff --git a/lms/static/images/follow-dog-ear.png b/lms/static/images/follow-dog-ear.png new file mode 100644 index 0000000000..af3bb4544a Binary files /dev/null and b/lms/static/images/follow-dog-ear.png differ diff --git a/lms/static/images/following-flag.png b/lms/static/images/following-flag.png new file mode 100644 index 0000000000..ac95c4cfea Binary files /dev/null and b/lms/static/images/following-flag.png differ diff --git a/lms/static/images/moderator-delete-icon.png b/lms/static/images/moderator-delete-icon.png new file mode 100644 index 0000000000..966ff2f9c2 Binary files /dev/null and b/lms/static/images/moderator-delete-icon.png differ diff --git a/lms/static/images/moderator-edit-icon.png b/lms/static/images/moderator-edit-icon.png new file mode 100644 index 0000000000..7e28eedf42 Binary files /dev/null and b/lms/static/images/moderator-edit-icon.png differ diff --git a/lms/static/images/new-post-icon.png b/lms/static/images/new-post-icon.png new file mode 100644 index 0000000000..bf16b9da89 Binary files /dev/null and b/lms/static/images/new-post-icon.png differ diff --git a/lms/static/sass/_discussion.scss b/lms/static/sass/_discussion.scss index aff05d21a1..01380faa77 100644 --- a/lms/static/sass/_discussion.scss +++ b/lms/static/sass/_discussion.scss @@ -1,99 +1,148 @@ -.container { - .discussion-wrapper { - display: table; - table-layout: fixed; - width: 100%; - height: 500px; - background: #fff; - border-radius: 3px; - border: 1px solid #aaa; - box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); - ul { - list-style: none; - margin: 0; - padding: 0; - border: 0; - outline: 0; - font-size: 100%; - font: inherit; - vertical-align: baseline; +@mixin blue-button { + display: block; + height: 33px; + margin: 12px; + padding: 0 15px; + border-radius: 3px; + border: 1px solid #4697c1; + background: -webkit-linear-gradient(top, #6dccf1, #38a8e5); + font-size: 13px; + font-weight: 700; + line-height: 30px; + color: #fff; + text-shadow: 0 1px 0 rgba(0, 0, 0, .4); + box-shadow: 0 1px 0 rgba(255, 255, 255, 0.4) inset, 0 1px 1px rgba(0, 0, 0, .15); + + &:hover { + border-color: #297095; + background: -webkit-linear-gradient(top, #4fbbe4, #2090d0); + } +} + +.discussion-body { + + .vote-btn { + float: right; + display: block; + height: 27px; + padding: 0 8px; + border-radius: 5px; + border: 1px solid #b2b2b2; + background: -webkit-linear-gradient(top, #fff 35%, #ebebeb); + box-shadow: 0 1px 1px rgba(0, 0, 0, .15); + font-size: 12px; + font-weight: 700; + line-height: 25px; + color: #333; + + .plus-icon { + float: left; + margin-right: 6px; + font-size: 18px; + color: #17b429; } - .discussion { - display: table-cell; - vertical-align: top; - width: 72.3%; - padding: 40px; + &.is-cast { + border-color: #379a42; + background: -webkit-linear-gradient(top, #50cc5e, #3db84b); + color: #fff; + text-shadow: 0 1px 0 rgba(0, 0, 0, .3); + box-shadow: 0 1px 0 rgba(255, 255, 255, .4) inset, 0 1px 2px rgba(0, 0, 0, .2); - h1 { - font-size: 28px; - font-weight: 700; - } - - .posted-details { - font-size: 12px; - font-style: italic; - color: #737373; - } - - p + p { - margin-top: 20px; - } - } - - .discussion-sidebar { - - display: table-cell; - vertical-align: top; - width: 27.7%; - background: #f6f6f6; - border-radius: 3px 0 0 3px; - border-right: 3px solid #bcbcbc; - - .sort-bar { - height: 27px; - border-bottom: 1px solid #a3a3a3; - background: -webkit-linear-gradient(top, #cdcdcd, #b6b6b6); - box-shadow: 0 1px 0 rgba(255, 255, 255, .4) inset; - - a { - display: block; - float: right; - height: 27px; - margin-right: 10px; - font-size: 11px; - font-weight: bold; - line-height: 23px; - color: #333; - text-shadow: 0 1px 0 rgba(255, 255, 255, .5); - - .sort-label { - font-size: 9px; - text-transform: uppercase; - } - } - } - - .board-drop-btn { - display: block; - height: 60px; - border-bottom: 1px solid #a3a3a3; - border-radius: 3px 0 0 0; - background: -webkit-linear-gradient(top, #ebebeb, #d9d9d9); - font-size: 16px; - font-weight: 700; - line-height: 58px; - text-align: center; - color: #333 !important; - text-shadow: 0 1px 0 rgba(255, 255, 255, .8); + .plus-icon { + color: #336a39; + text-shadow: 0 1px 0 rgba(255, 255, 255, .4); } } + } + + + .new-post-btn { + @include blue-button; + float: right; + } + + .new-post-icon { + display: block; + float: left; + width: 16px; + height: 17px; + margin: 7px 7px 0 0; + background: url(../images/new-post-icon.png) no-repeat; + } + + .post-search { + float: right; + } + + .post-search-field { + width: 280px; + height: 30px; + padding: 0 15px 0 30px; + margin-top: 14px; + border: 1px solid #acacac; + border-radius: 30px; + box-shadow: 0 1px 3px rgba(0, 0, 0, .1) inset, 0 1px 0 rgba(255, 255, 255, .5); + background: url(../images/search-icon.png) no-repeat 8px center #fff; + font-family: 'Open Sans', sans-serif; + font-weight: 400; + font-size: 13px; + line-height: 30px; + color: #333; + outline: 0; + -webkit-transition: border-color .1s; + + &:focus { + border-color: #4697c1; + } + } + + h1, ul, li, a, ol { + margin: 0; + padding: 0; + border: 0; + outline: 0; + font-size: 100%; + font: inherit; + vertical-align: baseline; + } + ul, li { + list-style-type: none; + } + a { + text-decoration: none; + color: #009fe2; + } + + display: table; + table-layout: fixed; + width: 100%; + height: 500px; + background: #fff; + border-radius: 3px; + border: 1px solid #aaa; + box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); + + .sidebar { + display: table-cell; + vertical-align: top; + width: 27.7%; + background: #f6f6f6; + border-radius: 3px 0 0 3px; + border-right: 1px solid #bcbcbc; .post-list { + background-color: #ddd; + + li:last-child a { + border-bottom: 1px solid #ddd; + } + a { + position: relative; display: block; height: 36px; padding: 0 10px; - border-bottom: 1px solid #ddd; + margin-bottom: 1px; background: #fff; font-size: 13px; font-weight: 700; @@ -104,6 +153,40 @@ font-weight: 400; color: #737373; } + + &.followed:after { + content: ''; + position: absolute; + top: 0; + right: 0; + width: 12px; + height: 12px; + background: url(../images/following-flag.png) no-repeat; + } + + &.active { + background: -webkit-linear-gradient(top, #96e0fd, #61c7fc); + border-color: #4697c1; + box-shadow: 0 1px 0 #4697c1, 0 -1px 0 #4697c1; + + .title { + color: #333; + } + + .votes-count, + .comments-count { + background: -webkit-linear-gradient(top, #3994c7, #4da7d3); + color: #fff; + + &:after { + color: #4da7d3; + } + } + + &.followed:after { + background-position: 0 -12px; + } + } } .title { @@ -115,8 +198,8 @@ overflow: hidden; } - .votes, - .comments { + .votes-count, + .comments-count { display: block; float: right; width: 32px; @@ -131,7 +214,7 @@ color: #767676; } - .comments { + .comments-count { position: relative; margin-left: 4px; @@ -156,898 +239,41 @@ } } } -} - - - -/*** OLD STUFF ***/ -/*** Variables ***/ - -$comment-margin-left: 30px; -$discussion-title-size: 1.6em; -$comment-title-size: 1.0em; -$post-font-size: 0.9em; -$comment-info-size: 0.75em; -$comment-font-size: 0.8em; -$discussion-input-width: 100%; - -$tag-background-color: #e7ecdd; -$tag-border-color: #babdb3; -$tag-text-color: #5b614f; - - - -/*** Mixins ***/ - -@mixin discussion-font { - font-family: inherit; -} - -@mixin discussion-clickable { - color: black; - &:hover { - text-decoration: none; - } -} - -@mixin standard-discussion-link { - text-decoration: none; - &:hover { - color: #1C71DD; - text-decoration: none; - } -} - -.discussion-loading { - background-image: url(../images/discussion/loading.gif); - width: 15px; - height: 15px; - margin-left: 2px; - display: inline-block; -} - -/*** Discussions ***/ - -.discussion { - - #open_close_accordion { - display: none; + .board-drop-btn { + display: block; + height: 60px; + border-bottom: 1px solid #a3a3a3; + border-radius: 3px 0 0 0; + background: -webkit-linear-gradient(top, #ebebeb, #d9d9d9); + font-size: 16px; + font-weight: 700; + line-height: 58px; + text-align: center; + color: #333; + text-shadow: 0 1px 0 rgba(255, 255, 255, .8); } - p + p, ul + p, ol + p { - margin-top: 0; - } - - /*** Sidebar ***/ - - .sidebar-module { - @include clearfix; - padding: 0 26px 24px; - margin-bottom: 24px; - border-bottom: 1px solid #d3d3d3; - font-size: 13px; - - header { - margin-bottom: 14px; - @include clearfix; - } - - h4 { - float: left; - font-size: 15px; - font-weight: bold; - } - - .sidebar-new-post-button, .sidebar-promote-moderator-button { - @include button; - } - - .sidebar-revoke-moderator-button { - @include button(simple, gray); - } - - .sidebar-new-post-button, .sidebar-promote-moderator-button, .sidebar-revoke-moderator-button { - display: block; - box-sizing: border-box; - width: 100%; - margin: 20px 0; - padding: 11px; - font-size: 1.1em; - text-align: center; - - &:hover { - text-decoration: none; - } - } - - .sidebar-new-post-button { - margin: 40px 0 20px 0; - } - - .sidebar-view-all { - float: right; - font-size: 13px; - line-height: 1.6em; - @include standard-discussion-link; - } - - .discussion-sidebar-following-list { - li { - @include clearfix; - margin-bottom: 8px; - border: none; - } - - a { - @include standard-discussion-link; - background: none; - - span { - line-height: 1.3; - } - } - } - - .discussion-sidebar-tags-list li { - @include clearfix; - border-bottom: none; - } - - .sidebar-tag-count { - color: #9a9a9a; - font-size: .85em; - line-height: 3em; - } - - .sidebar-following-name { - float: left; - width: 80%; - } - - .sidebar-vote-count { - float: right; - width: 20%; - text-align: right; - color: #9a9a9a; - } - -//user profile - - .user-profile { - @extend .sidebar; - margin-top: 24px; - } - - .sidebar-username { - font-size: 1.5em; - font-weight: bold; - line-height: 1.5em; - margin-top: 20px; - } - - .sidebar-user-roles { - color: darkGray; - font-style: italic; - margin-bottom: 15px; - } - - .sidebar-threads-count, .sidebar-comments-count { - - span { - font-size: 1.5em; - font-weight: bold; - line-height: 1.5em; - margin-right: 10px; - } - } - } - - .discussion-non-content { - margin-left: flex-gutter(); - } - - /*** Post ***/ - - .discussion-title { - @include discussion-font; - @include discussion-clickable; - display: inline-block; - font-size: $discussion-title-size; - font-weight: bold; - margin-bottom: flex-gutter(6); - } - - .discussion-title-wrapper { - .discussion-watch-discussion, .discussion-unwatch-discussion { - @include discussion-font; - display: none; - font-size: $comment-info-size; - margin-left: 5px; - } - } - - .discussion-right-wrapper { - min-height: 40px; - margin: 24px 0 24px 68px; - } - - .admin-actions { - float: right; - margin: 0.4em 1em 0 2em; - padding: 0; - - li { - margin-bottom: 6px !important; - } + .sort-bar { + height: 27px; + border-bottom: 1px solid #a3a3a3; + background: -webkit-linear-gradient(top, #cdcdcd, #b6b6b6); + box-shadow: 0 1px 0 rgba(255, 255, 255, .4) inset; a { display: block; - height: 25px; - padding-left: 25px; - border-radius: 50%; - background: url(../images/admin-actions-sprite.png) no-repeat; - font-size: .8em; - line-height: 25px; - color: #b8b8b8; - @include transition(color, .1s); - - &:hover { - text-decoration: none; - } - - &.admin-endorse { - background-position: 0 0; - - &:hover { - color: #63b141; - background-position: 0 -75px; - } - } - - &.admin-edit { - background-position: 0 -25px; - - &:hover { - color: #009fe2; - background-position: 0 -100px; - } - } - - &.admin-delete { - background-position: 0 -50px; - - &:hover { - color: #d45050; - background-position: 0 -125px; - } - } - } - } - - .comments { - .admin-actions { - margin-top: 0; - - li { - margin-bottom: 2px !important; - } - - a { - width: 20px; - height: 20px; - padding-left: 0; - overflow: hidden; - text-indent: -9999px; - - &.admin-endorse { - background-position: 0 -150px; - - &:hover { - background-position: 0 -225px; - } - } - - &.admin-edit { - background-position: 0 -175px; - - &:hover { - background-position: 0 -250px; - } - } - - &.admin-delete { - background-position: 0 -200px; - - &:hover { - background-position: 0 -275px; - } - } - } - } - } - - - - - /*** thread ***/ - - .thread { - //display: none; - - .search-highlight { - display: inline; - font-weight: bold; - background-color: lightyellow; - } - - .thread-title { - @include discussion-font; - @include discussion-clickable; - display: block; - margin-bottom: 1em; - font-size: $comment-title-size; - font-weight: bold; - line-height: 1.4em; - } - - .thread-body, .content-body { - @include discussion-font; - font-size: $post-font-size; - margin-bottom: 4px; - margin-top: 3px; - - p { - @include discussion-font; - } - } - - .thread-tags { - display: inline-block; - } - - .info { - @include discussion-font; - color: gray; - font-size: $comment-info-size; - font-style: italic; - margin-top: 1em; - - a:hover { - text-decoration: none; - color: #1C71DD; - } - - .comment-time { - display: inline; - float: right; - margin-right: 1em; - } - - .show-comments-wrapper { - display: inline; - margin-right: 20px; - } - - .discussion-actions { - display: inline; - margin: 0; - padding: 0; - - li { - display: inline; - margin-right: 20px; - } - } - - .discussion-link { - @include discussion-font; - color: #1d9dd9; - display: inline; - - &.discussion-unfollow-thread { - color: #dea03e; - } - } - } - - .discussion-content { - border-top: lightgray 1px solid; - overflow: hidden; - // padding: 1.5% 0; - - .discussion-reply-new { - @include discussion-font; - margin-left: 68px; - - .reply-body { - @include discussion-font; - display: block; - font-size: $post-font-size; - margin-top: 10px; - width: 95%; - } - - .reply-post-control { - margin-top: 1%; - } - } - } - - //COMMENT STYLES - .comments { - overflow: hidden; - - .discussion-votes { - margin-top: 8px; - } - - .discussion-right-wrapper { - margin: 10px 0 10px 68px; - } - - .comment { - margin-left: 68px; - .comment-body, .content-body { - @include discussion-font; - color: black; - display: block; - font-size: $comment-font-size; - margin-top: 3px; - } - - &.endorsed { - > .discussion-content { - background-color: #fcfcea; - } - } - } - } - } - - - - - /*** Sorting ***/ - - .discussion-sort { - float: right; - font-size: 0.8em; - margin-top: -36px; - - .discussion-label { - display: block; - float: left; - padding: 0 14px; - line-height: 34px; - } - - .discussion-sort-link { - display: block; - float: left; - padding: 0 14px; - line-height: 34px; - - &:hover { - color: #1C71DD; - text-decoration: none; - } - } - - .discussion-sort-link.sorted { - color: #000; - border-bottom: 2px solid #000; - } - } - - /*** Search ***/ - - .search-wrapper-inline { - display: inline-block; - margin-top: 3%; - width: 80%; - } - - .search-wrapper { - margin-bottom: 50px; - margin-left: .5%; - } - - .discussion-search-form { - display: inline-block; - margin-bottom: 1%; - width: flex-grid(12); - - .discussion-link { - @include button(simple, #999); - color: white; - display: inline-block; - font-size: inherit; - font-weight: bold; - margin-left: 1%; - padding-top: 9px; - text-decoration: none; - } - - .discussion-search-text { - @include discussion-font; - } - - .search-input { - float: left; - font: inherit; - font-style: normal; - // width: 72%; - width: flex-grid(8); - margin-left: flex-grid(1); - } - } - - .search-within { - display: block; - margin-bottom: 3%; - } - - .discussion-search-within-board { - font: inherit; - font-size: $post-font-size; - font-style: normal; - } - - /*** buttons ***/ - - .control-button { - @include button; - @include discussion-font; - background-color: #959595; - @include background-image(linear-gradient(top, #959595, #7B7B7B)); - border: 1px solid #6F6F6F; - @include box-shadow(inset 0 1px 0 #A2A2A2, 0 0 3px #CCC); - color: white; - display: inline-block; - font-size: inherit; - font-weight: bold; - margin-bottom: 3%; - padding-top: 9px; - width: inherit; - text-decoration: none; - text-shadow: none; - - &:hover { - background-color: #A2A2A2; - @include background-image(linear-gradient(top, #A2A2A2, #7B7B7B)); - border: 1px solid #555; - @include box-shadow(inset 0 1px 0 #BBB, 0 0 3px #CCC); - } - } - - .follow-wrapper { - display: inline; - } - - /*** votes ***/ - - .discussion-votes { - float: left; - width: 60px; - margin-top: 18px; - text-align: center; - - .discussion-vote { - display: block; - width: 50px; - height: 17px; - margin: auto; - background: url(../images/vote-arrows.png) no-repeat; - font-size: 15px; - font-weight: bold; - color: black; - @include hide-text; - @include transition(all, 0, easeOut); - } - - .discussion-vote-up { - margin-bottom: 5px; - background-position: -50px -3px; - - &:hover { - background-position: -50px -5px; - @include transition-duration(0.05s); - } - - &.voted { - background-position: 0 -3px; - color: #1C71DD; - @include transition-duration(0); - } - } - - .discussion-vote-down { - margin-top: 7px; - background-position: -50px -30px; - - &:hover { - background-position: -50px -28px; - @include transition-duration(0.05s); - } - - &.voted { - background-position: 0 -30px; - color: #1C71DD; - @include transition-duration(0); - } - } - - .discussion-vote-count { - @include discussion-font; - font-size: $post-font-size; - } - - .discussion-votes-point { - font-size: 1.1em; - font-weight: bold; - color: #9a9a9a; - } - } - - - /*** new post ***/ - - .new-post-form, .discussion-thread-edit { - - .title-input, .body-input { - display: block !important; - font: inherit; - font-style: normal; - //width: $discussion-input-width !important; - } - - .new-post-similar-posts-wrapper { - @include border-radius(3px); - border: 1px solid #EEE; - font-size: $post-font-size; - line-height: 150%; - margin-top: 1%; - padding: 1% 1.5%; - } - - .hide-similar-posts { float: right; - } - - .new-post-similar-posts { - font: inherit; - .similar-post { - display: block; - line-height: 150%; - } - } - - .discussion-errors { - color: #8F0E0E; - display: block; - margin-left: -5%; - } - - .new-post-body { - } - - .tagsinput { - background: #FAFAFA; - border: 1px solid #C8C8C8; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - -ms-border-radius: 3px; - -o-border-radius: 3px; - border-radius: 3px; - -webkit-box-shadow: 0 1px 0 0 rgba(255, 255, 255, 0.6), inset 0 0 3px 0 rgba(0, 0, 0, 0.1); - -moz-box-shadow: 0 1px 0 0 rgba(255, 255, 255, 0.6), inset 0 0 3px 0 rgba(0, 0, 0, 0.1); - box-shadow: 0 1px 0 0 rgba(255, 255, 255, 0.6), inset 0 0 3px 0 rgba(0, 0, 0, 0.1); - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - margin-top: flex-gutter(); - vertical-align: top; - -webkit-font-smoothing: antialiased; - } - } - - .discussion-content-edit, .discussion-reply-new, .new-post-form { - margin: 10px 0 10px 0; - - .discussion-errors { - color: #8F0E0E; - display: block; - font: inherit; - font-size: $post_font_size; - list-style: none; - margin-left: -3%; - padding-left: 2em; - } - - a:hover { - color: #1C71DD; - text-decoration: none; - } - - .new-post-title { - display: block; - padding: 5px 12px; - border-width: 1px; - width: 100%; - } - - .thread-title-edit { - width: 100%; - } - - &.collapsed { - .new-post-title { - display: none; - visibility: hidden; - } - - .wmd-button-row { - height: 0; - } - - .wmd-input { - height: 100px; - @include border-radius(3px); - } - - .wmd-preview { - height: 0; - padding: 0; - border-width: 0; - } - - .post-options { - height: 0; - } - - .post-control { - display: none; - } - - .tagsinput { - display: none; - } - } - - .new-post-control { - margin-left: 75%; - margin-top: 1%; - - .discussion-cancel-post { - margin-right: 1.5%; - } - } - - .reply-post-control { - - .discussion-cancel-post { - margin-right: 1.5%; - } - } - - .edit-post-control { - margin-top: 1%; - - .discussion-cancel-update { - margin-right: 1.5%; - } - } - - .control-button { - @include button; - @include discussion-font; - margin-right: 16px; - padding-top: 9px; - color: white; - display: inline-block; - font-size: inherit; + height: 27px; + margin-right: 10px; + font-size: 11px; font-weight: bold; - text-decoration: none; - width: inherit; + line-height: 23px; + color: #333; + text-shadow: 0 1px 0 rgba(255, 255, 255, .5); - &:hover { - color: white; - } - } - - label { - display: inline; - font-family: $sans-serif; - font-size: .8em; - font-style: normal; - font-weight: 400; - } - } - - .discussion-content-edit { - margin: 3%; - } - - .new-post-form { - margin: 10px 0 40px 0; - } - - .discussion-reply-new { - - .discussion-auto-watch { - margin-left: 2%; - } - } - - .thread-tag { - background: $tag-background-color; - border: 1px solid $tag-border-color; - -moz-border-radius: 2px; - -webkit-border-radius: 2px; - color: $tag-text-color; - float: left; - font-size: 13px; - margin: 5px 7px 5px 0; - padding: 5px 7px; - text-decoration: none; - - &:hover { - border-color: #7b8761; - color: #2f381c; - text-decoration: none; - } - } - - /*** pagination ***/ - - .discussion-paginator { - font-size: $post-font-size; - margin-bottom: 10px; - margin-top: 20px; - text-align: center; - - div { - display: inline-block; - font-weight: bold; - margin: 0 5px; - - a { - background: #EEE; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - -ms-border-radius: 3px; - -o-border-radius: 3px; - border-radius: 3px; - color: black; - font-weight: normal; - padding: 4px 10px; - text-decoration: none; - - &:hover { - background: #DDD; - } - } - } - } - - &.inline-discussion, .forum-discussion, .user-discussion { - .new-post-form { - margin: 24px 60px; - - .post-options { - margin: 8px 0 16px 0; - overflow: hidden; - - label { - margin-right: 15px; - display: inline; - } - } - - .post-control { - overflow: hidden; - margin: 0 0 5% 0; + .sort-label { + font-size: 9px; + text-transform: uppercase; } } } @@ -1055,138 +281,197 @@ $tag-text-color: #5b614f; -/*** base editor styles ***/ -.wmd-panel { - width: 100%; - min-width: 500px; + + + + + + + + +.global-discussion-actions { + height: 60px; + background: -webkit-linear-gradient(top, #ebebeb, #d9d9d9); + border-radius: 0 3px 0 0; + border-bottom: 1px solid #bcbcbc; } -.wmd-button-bar { - width: 100%; - background-color: Silver; -} -.wmd-input { - height: 150px; - width: 100%; - background-color: #e9e9e9; - border: 1px solid #c8c8c8; - font-family: Monaco, 'Lucida Console', monospace; - font-style: normal; - font-size: 0.8em; - line-height: 1.6em; - @include border-radius(3px 3px 0 0); - &::-webkit-input-placeholder { + + + + + + + + +.discussion-article { + position: relative; + display: table-cell; + vertical-align: top; + width: 72.3%; + padding: 40px; + + h1 { + font-size: 28px; + font-weight: 700; + } + + .posted-details { + font-size: 12px; + font-style: italic; color: #888; } + + p + p { + margin-top: 20px; + } + + .dogear { + display: block; + position: absolute; + top: 0; + right: -1px; + width: 52px; + height: 51px; + background: url(../images/follow-dog-ear.png) 0 -51px no-repeat; + + &.is-followed { + background-position: 0 0; + } + } } -.wmd-preview { - position: relative; - font-family: $sans-serif; - padding: 25px 20px 10px 20px; - margin-bottom: 5px; - box-sizing: border-box; - border: 1px solid #c8c8c8; - border-top-width: 0; - @include border-radius(0 0 3px 3px); - overflow: hidden; - @include transition(all, .2s, easeOut); +.discussion-post header, +.responses li header { + margin-bottom: 20px; +} - &:before { - content: 'PREVIEW'; - position: absolute; - top: 3px; - left: 5px; - font-size: 11px; - color: #bbb; +.responses { + margin-top: 40px; + + > li { + margin: 0 -10px; + padding: 30px; + border-radius: 3px; + border: 1px solid #b2b2b2; + box-shadow: 0 1px 3px rgba(0, 0, 0, .15); + } + + .posted-by { + font-weight: 700; + } +} + +.endorse-btn { + display: block; + float: right; + width: 27px; + height: 27px; + margin-right: 10px; + border-radius: 27px; + border: 1px solid #a0a0a0; + background: -webkit-linear-gradient(top, #fff 35%, #ebebeb); + box-shadow: 0 1px 1px rgba(0, 0, 0, .1); + + .check-icon { + display: block; + width: 13px; + height: 12px; + margin: 8px auto; + background: url(../images/endorse-icon.png) no-repeat; + } + + &.is-endorsed { + border: 1px solid #4697c1; + background: -webkit-linear-gradient(top, #6dccf1, #38a8e5); + box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1), 0 1px 0 rgba(255, 255, 255, .4) inset; + + .check-icon { + background-position: 0 -12px; + } + } +} + +.comments { + margin-top: 20px; + border-top: 1px solid #ddd; + + li { + background: #f6f6f6; + border-bottom: 1px solid #ddd; } p { - font-family: $sans-serif; + font-size: 13px; + padding: 10px 20px; + + .posted-details { + font-size: 11px; + white-space: nowrap; + } } - background-color: #fafafa; } -.wmd-button-row { - position: relative; - margin-left: 5px; - margin-right: 5px; - margin-bottom: 5px; - margin-top: 10px; - padding: 0px; - height: 20px; - overflow: hidden; - @include transition(all, .2s, easeOut); +.comment-form { + padding: 8px 20px; } -.wmd-spacer { - width: 1px; - height: 20px; - margin-left: 14px; +.comment-form-input { + width: 100%; + height: 31px; + padding: 0 10px; + box-sizing: border-box; + border: 1px solid #b2b2b2; + border-radius: 3px; + box-shadow: 0 1px 3px rgba(0, 0, 0, .1) inset; + -webkit-transition: border-color .1s; + outline: 0; - position: absolute; - background-color: Silver; - display: inline-block; - list-style: none; + &:focus { + border-color: #4697c1; + } } -.wmd-button { - width: 20px; - height: 20px; - padding-left: 2px; - padding-right: 3px; - position: absolute; - display: inline-block; - list-style: none; - cursor: pointer; -} +.moderator-actions { + margin-top: 20px; + @include clearfix; -.wmd-button > span { - background-image: url('/static/images/wmd-buttons.png'); - background-repeat: no-repeat; - background-position: 0px 0px; - width: 20px; - height: 20px; - display: inline-block; -} + li { + float: left; + margin-right: 8px; + } -.wmd-spacer1 { - left: 50px; -} -.wmd-spacer2 { - left: 175px; -} + a { + display: block; + height: 26px; + padding: 0 12px; + border-radius: 3px; + border: 1px solid #b2b2b2; + background: -webkit-linear-gradient(top, #fff 35%, #ebebeb); + font-size: 13px; + line-height: 24px; + color: #737373; + box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1); -.wmd-spacer3 { - left: 300px; -} + .delete-icon { + display: block; + float: left; + width: 10px; + height: 10px; + margin: 8px 4px 0 0; + background: url(../images/moderator-delete-icon.png) no-repeat; + } -.wmd-prompt-background { - background-color: Black; -} - -.wmd-prompt-dialog { - border: 1px solid #999999; - background-color: #F5F5F5; -} - -.wmd-prompt-dialog > div { - font-size: 0.8em; - font-family: arial, helvetica, sans-serif; -} - - -.wmd-prompt-dialog > form > input[type="text"] { - border: 1px solid #999999; - color: black; -} - -.wmd-prompt-dialog > form > input[type="button"] { - border: 1px solid #888888; - font-family: trebuchet MS, helvetica, sans-serif; - font-size: 0.8em; - font-weight: bold; + .edit-icon { + display: block; + float: left; + width: 10px; + height: 10px; + margin: 7px 4px 0 0; + background: url(../images/moderator-edit-icon.png) no-repeat; + } + } } diff --git a/lms/templates/discussion/_single_thread.html b/lms/templates/discussion/_single_thread.html index ccf106a6df..1939bfd753 100644 --- a/lms/templates/discussion/_single_thread.html +++ b/lms/templates/discussion/_single_thread.html @@ -1,12 +1,33 @@ <%namespace name="renderer" file="_content_renderer.html"/> -
- ${thread['title'] | h} -

sometime by Foo

-
- ${renderer.render_content_with_comments(thread)} +
+
    + % for reply in thread.get("children", []): +
  1. +
    ${reply['body']}
    +
      + % for comment in reply.get("children", []): +
    1. ${comment['body']}

    2. + % endfor +
    +
  2. + % endfor +
+ <%include file="_js_data.html" /> diff --git a/lms/templates/discussion/single_thread.html b/lms/templates/discussion/single_thread.html index 1e05475762..3024198750 100644 --- a/lms/templates/discussion/single_thread.html +++ b/lms/templates/discussion/single_thread.html @@ -1,4 +1,5 @@ <%! import django_comment_client.helpers as helpers %> +<%! from django.template.defaultfilters import escapejs %> <%inherit file="../main.html" /> <%namespace name='static' file='../static_content.html'/> <%block name="bodyclass">discussion @@ -16,48 +17,47 @@ <%include file="../courseware/course_navigation.html" args="active_page='discussion'" /> -
-
- -
+
+ +
+
+ New Post +
+ +
+
+ ${content.decode('utf-8')} -
+ + + - - -
-
-
- -
- -
- ${content.decode('utf-8')} -
-
-
+