diff --git a/Gemfile b/Gemfile index ecfc613b..d5ac1fad 100644 --- a/Gemfile +++ b/Gemfile @@ -28,7 +28,6 @@ gem 'devise' gem 'devise-async' gem 'bootstrap_form' gem 'font-kit-rails' -gem 'nprogress-rails' gem 'font-awesome-rails', '~> 4.2.0.0' gem 'rails-assets-growl' gem "paperclip", "~> 4.2" @@ -38,7 +37,6 @@ gem 'ruby-progressbar' gem 'rails_admin' -gem 'twitter' gem 'sidekiq' gem 'sinatra', require: false @@ -50,6 +48,11 @@ gem 'redcarpet' # OmniAuth and providers gem 'omniauth' gem 'omniauth-twitter' +gem 'omniauth-tumblr' + +# OAuth clients +gem 'twitter' +gem 'tumblr_client' gem 'foreman' gem 'redis' diff --git a/Gemfile.lock b/Gemfile.lock index 9e09452c..2558c5a5 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -111,6 +111,8 @@ GEM i18n (~> 0.5) faraday (0.9.0) multipart-post (>= 1.2, < 3) + faraday_middleware (0.9.1) + faraday (>= 0.7.4, < 0.10) font-awesome-rails (4.2.0.0) railties (>= 3.2, < 5.0) font-kit-rails (1.1.0) @@ -163,7 +165,6 @@ GEM mini_portile (~> 0.6.0) nokogumbo (1.2.0) nokogiri - nprogress-rails (0.1.6.3) oauth (0.4.7) omniauth (1.2.2) hashie (>= 1.2, < 4) @@ -171,6 +172,8 @@ GEM omniauth-oauth (1.0.1) oauth omniauth (~> 1.0) + omniauth-tumblr (1.1) + omniauth-oauth (~> 1.0) omniauth-twitter (1.1.0) multi_json (~> 1.3) omniauth-oauth (~> 1.0) @@ -309,6 +312,13 @@ GEM tilt (1.4.1) timers (4.0.1) hitimes + tumblr_client (0.8.5) + faraday (~> 0.9.0) + faraday_middleware (~> 0.9.0) + json + mime-types + oauth + simple_oauth turbolinks (2.5.3) coffee-rails twitter (5.13.0) @@ -368,8 +378,8 @@ DEPENDENCIES jquery-rails jquery-turbolinks mysql2 - nprogress-rails omniauth + omniauth-tumblr omniauth-twitter paperclip (~> 4.2) pg @@ -391,6 +401,7 @@ DEPENDENCIES spring sweetalert-rails thin + tumblr_client turbolinks twitter uglifier (>= 1.3.0) diff --git a/Rakefile b/Rakefile index 9c92daf4..8c169681 100644 --- a/Rakefile +++ b/Rakefile @@ -72,7 +72,7 @@ namespace :justask do user.save! puts "#{user.screen_name} no longer an admin." end - + desc "Gives moderator status to an user." task :mod, [:screen_name] => :environment do |t, args| fail "screen name required" if args[:screen_name].nil? @@ -90,7 +90,27 @@ namespace :justask do fail "user #{args[:screen_name]} not found" if user.nil? user.moderator = false user.save! - puts "#{user.screen_name} no longer an moderator." + puts "#{user.screen_name} is no longer an moderator." + end + + desc "Hits an user with the banhammer." + task :ban, [:screen_name] => :environment do |t, args| + fail "screen name required" if args[:screen_name].nil? + user = User.find_by_screen_name(args[:screen_name]) + fail "user #{args[:screen_name]} not found" if user.nil? + user.banned = true + user.save! + puts "#{user.screen_name} got hit by\033[5m YE OLDE BANHAMMER\033[0m!!1!" + end + + desc "Removes banned status from an user." + task :unban, [:screen_name] => :environment do |t, args| + fail "screen name required" if args[:screen_name].nil? + user = User.find_by_screen_name(args[:screen_name]) + fail "user #{args[:screen_name]} not found" if user.nil? + user.banned = false + user.save! + puts "#{user.screen_name} is no longer banned." end desc "Gives supporter status to an user." diff --git a/app/assets/javascripts/application.js.erb.coffee b/app/assets/javascripts/application.js.erb.coffee index 5842510d..608983d5 100644 --- a/app/assets/javascripts/application.js.erb.coffee +++ b/app/assets/javascripts/application.js.erb.coffee @@ -3,16 +3,13 @@ #= require jquery.turbolinks #= require turbolinks #= require bootstrap -#= require nprogress -#= require nprogress-turbolinks #= require growl #= require cheet #= require jquery.guillotine #= require sweet-alert #= require_tree . -NProgress.configure - showSpinner: false +Turbolinks.enableProgressBar() window.showNotification = (text, success=true) -> args = diff --git a/app/assets/javascripts/piwik.js.erb b/app/assets/javascripts/piwik.js.erb new file mode 100644 index 00000000..5e716619 --- /dev/null +++ b/app/assets/javascripts/piwik.js.erb @@ -0,0 +1,18 @@ +// -*- C++ -*- + +<% if Rails.env.production? %> +var _paq = _paq || []; +_paq.push(['trackPageView']); +_paq.push(['enableLinkTracking']); +_paq.push(['setCustomUrl', document.location]); +_paq.push(['setDocumentTitle', document.title]); +(function() { + var u="//stat.rrerr.net/"; + _paq.push(['setTrackerUrl', u+'piwik.php']); + _paq.push(['setSiteId', 9]); + var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0]; + g.type='text/javascript'; g.async=true; g.defer=true; g.src=u+'piwik.js'; s.parentNode.insertBefore(g,s); +})(); +<% else %> +console.log("i track'd ur bich"); +<% end %> \ No newline at end of file diff --git a/app/assets/stylesheets/application.css.scss b/app/assets/stylesheets/application.css.scss index e43fa907..06528d5e 100644 --- a/app/assets/stylesheets/application.css.scss +++ b/app/assets/stylesheets/application.css.scss @@ -34,6 +34,8 @@ body { padding-top: $navbar-height; } @import "font-awesome"; -$nprogress-color: darken($navbar-inverse-bg, 15%); -@import 'nprogress'; -@import 'nprogress-bootstrap'; +html.turbolinks-progress-bar::before { + background-color: darken($navbar-inverse-bg, 15%) !important; + box-shadow: 0px 0px 10px darken($navbar-inverse-bg, 15%), 0px 0px 5px darken($navbar-inverse-bg, 15%); + height: 2px !important; +} diff --git a/app/assets/stylesheets/scss/answerbox.scss b/app/assets/stylesheets/scss/answerbox.scss index ff85cb91..71468b1e 100644 --- a/app/assets/stylesheets/scss/answerbox.scss +++ b/app/assets/stylesheets/scss/answerbox.scss @@ -1,5 +1,5 @@ -.text-muted a, .answerbox .text-muted a:hover { - color: $gray-dark; +.answerbox .text-muted a, .answerbox .text-muted a:hover { + color: $gray; text-decoration: none; } @@ -23,6 +23,11 @@ } .answerbox--question-text { - font-weight: bold; - color: $gray-darker; + color: $gray; +} + +.answerbox--answer-text { + font-size: 16px; + color: #000; + line-height: 1.3em; } \ No newline at end of file diff --git a/app/assets/stylesheets/scss/user.scss b/app/assets/stylesheets/scss/user.scss index 14c314fe..55101e25 100644 --- a/app/assets/stylesheets/scss/user.scss +++ b/app/assets/stylesheets/scss/user.scss @@ -120,4 +120,8 @@ .panel-badge-warning { background-color: #FF9800; +} + +.user--banned { + text-decoration: line-through !important; } \ No newline at end of file diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index f02cdaa6..42840939 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -4,6 +4,18 @@ class ApplicationController < ActionController::Base protect_from_forgery with: :exception before_filter :configure_permitted_parameters, if: :devise_controller? + before_filter :banned? + + # check if user got hit by the banhammer of doom + def banned? + if current_user.present? && current_user.banned? + name = current_user.screen_name + # obligatory '2001: A Space Odyssey' reference + flash[:notice] = "I'm sorry, #{name}, I'm afraid I can't do that." + sign_out current_user + redirect_to new_user_session_path + end + end include ApplicationHelper diff --git a/app/controllers/notifications_controller.rb b/app/controllers/notifications_controller.rb index 5ad7c0c3..073427e9 100644 --- a/app/controllers/notifications_controller.rb +++ b/app/controllers/notifications_controller.rb @@ -7,6 +7,10 @@ class NotificationsController < ApplicationController Notification.for(current_user) else Notification.for(current_user).where('LOWER(target_type) = ?', @type) - end + end.paginate(page: params[:page]) + respond_to do |format| + format.html + format.js + end end end diff --git a/app/helpers/markdown_helper.rb b/app/helpers/markdown_helper.rb index 169900e5..b385f696 100644 --- a/app/helpers/markdown_helper.rb +++ b/app/helpers/markdown_helper.rb @@ -1,21 +1,12 @@ module MarkdownHelper def markdown(content) - md = Redcarpet::Markdown.new(FlavoredMarkdown, - filter_html: true, - escape_html: true, - no_images: true, - no_styles: true, - safe_links_only: true, - xhtml: false, - hard_wrap: true, - no_intra_emphasis: true, - tables: true, - fenced_code_blocks: true, - autolink: true, - disable_indented_code_blocks: true, - strikethrough: true, - superscript: true) + md = Redcarpet::Markdown.new(FlavoredMarkdown, MARKDOWN_OPTS) Sanitize.fragment(md.render(content), EVIL_TAGS).html_safe end + + def strip_markdown(content) + md = Redcarpet::Markdown.new(Redcarpet::Render::StripDown, MARKDOWN_OPTS) + CGI.unescape_html(Sanitize.fragment(md.render(content), EVIL_TAGS)).strip + end end \ No newline at end of file diff --git a/app/helpers/user_helper.rb b/app/helpers/user_helper.rb index babb3f22..4e3e599d 100644 --- a/app/helpers/user_helper.rb +++ b/app/helpers/user_helper.rb @@ -4,7 +4,7 @@ module UserHelper def user_screen_name(user, anonymous=false, url=true) return APP_CONFIG['anonymous_name'] if user.nil? || anonymous name = user.display_name.blank? ? user.screen_name : user.display_name - return link_to(name, show_user_profile_path(user.screen_name)) if url + return link_to(name, show_user_profile_path(user.screen_name), class: "#{"user--banned" if user.banned?}") if url name end end diff --git a/app/models/services/tumblr.rb b/app/models/services/tumblr.rb new file mode 100644 index 00000000..d6631b9f --- /dev/null +++ b/app/models/services/tumblr.rb @@ -0,0 +1,45 @@ +class Services::Tumblr < Service + include Rails.application.routes.url_helpers + include MarkdownHelper + + def provider + "tumblr" + end + + def post(answer) + Rails.logger.debug "posting to Tumblr {'answer' => #{answer.id}, 'user' => #{self.user_id}}" + create_post answer + end + + private + + def client + @client ||= Tumblr::Client.new( + consumer_key: APP_CONFIG['sharing']['tumblr']['consumer_key'], + consumer_secret: APP_CONFIG['sharing']['tumblr']['consumer_secret'], + oauth_token: self.access_token, + oauth_token_secret: self.access_secret + ) + end + + def create_post(answer) + answer_url = show_user_answer_url( + id: answer.id, + username: answer.user.screen_name, + host: APP_CONFIG['hostname'], + protocol: (APP_CONFIG['https'] ? :https : :http) + ) + asker = if answer.question.author_is_anonymous? + APP_CONFIG['anonymous_name'] + else + answer.question.user.display_name.blank? ? answer.question.user.screen_name : answer.question.user.display_name + end + client.text( + self.uid, + title: "#{asker} asked: #{answer.question.content}", + body: "#{answer.content}\n\n[Smile or comment on the answer here](#{answer_url})", + format: 'markdown', + tweet: 'off' + ) + end +end \ No newline at end of file diff --git a/app/models/services/twitter.rb b/app/models/services/twitter.rb index b8b33d47..bd3b6ca8 100644 --- a/app/models/services/twitter.rb +++ b/app/models/services/twitter.rb @@ -1,5 +1,6 @@ class Services::Twitter < Service include Rails.application.routes.url_helpers + include MarkdownHelper def provider "twitter" @@ -27,8 +28,8 @@ class Services::Twitter < Service def prepare_tweet(answer) # TODO: improve this. - question_content = answer.question.content - answer_content = answer.content + question_content = strip_markdown answer.question.content + answer_content = strip_markdown answer.content answer_url = show_user_answer_url( id: answer.id, username: answer.user.screen_name, diff --git a/app/models/user.rb b/app/models/user.rb index 9d372b3e..30f8cf81 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -31,11 +31,11 @@ class User < ActiveRecord::Base SCREEN_NAME_REGEX = /\A[a-zA-Z0-9_]{1,16}\z/ WEBSITE_REGEX = /https?:\/\/([A-Za-z.\-]+)\/?(?:.*)/i - validates :screen_name, presence: true, format: { with: SCREEN_NAME_REGEX }, uniqueness: { case_sensitive: false }#, - #exclusion: { in: %w(justask_admin retrospring_admin admin justask retrospring support about public - # notifications inbox sign_in sign_up sidekiq moderation moderator mod administrator - # siteadmin site_admin), - # message: "%{value} is reserved." } + before_validation do + screen_name.strip! + end + + validates :screen_name, presence: true, format: { with: SCREEN_NAME_REGEX }, uniqueness: { case_sensitive: false }, screen_name: true validates :display_name, length: { maximum: 50 } validates :bio, length: { maximum: 200 } diff --git a/app/validators/screen_name_validator.rb b/app/validators/screen_name_validator.rb new file mode 100644 index 00000000..e0158662 --- /dev/null +++ b/app/validators/screen_name_validator.rb @@ -0,0 +1,11 @@ +class ScreenNameValidator < ActiveModel::EachValidator + FORBIDDEN_SCREEN_NAMES = %w(justask_admin retrospring_admin admin justask retrospring support about public + notifications inbox sign_in sign_up sidekiq moderation moderator mod administrator + siteadmin site_admin help retro_spring retroospring retrosprlng niisding nllsding) + + def validate_each(record, attribute, value) + if FORBIDDEN_SCREEN_NAMES.include? value.downcase + record.errors[attribute] << "Thou shalt not use this username! Please choose another one." + end + end +end \ No newline at end of file diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml index 4306477a..b72d3d52 100644 --- a/app/views/layouts/application.html.haml +++ b/app/views/layouts/application.html.haml @@ -5,8 +5,13 @@ %meta{'http-equiv' => 'X-UA-Compatible' ,content: 'IE=edge'} %meta{name: 'viewport', content: 'width=device-width, initial-scale=1, user-scalable=no'} %meta{name: 'theme-color', content: '#0C84E4'} + %meta{name: "mobile-web-app-capable", content: "yes"} %meta{name: "apple-mobile-web-app-capable", content: "yes"} %meta{name: 'apple-mobile-web-app-status-bar-style', content: 'black-translucent'} + %link{rel: 'apple-touch-icon', href: '/apple-touch-icon-precomposed.png'} + %link{rel: 'icon', href: '/images/favicon/favicon-16.png', sizes: '16x16'} + %link{rel: 'icon', href: '/icon-152.png', sizes: '152x152'} + %link{rel: 'icon', href: '/images/favicon/favicon-32.png', sizes: '32x32'} %title= APP_CONFIG['site_name'] = stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true = javascript_include_tag 'application', 'data-turbolinks-track' => true @@ -27,19 +32,6 @@ = debug params - if Rails.env.production? - :javascript - var _paq = _paq || []; - _paq.push(['trackPageView']); - _paq.push(['enableLinkTracking']); - _paq.push(['setCustomUrl', document.location]); - _paq.push(['setDocumentTitle', document.title]); - (function() { - var u="//stat.rrerr.net/"; - _paq.push(['setTrackerUrl', u+'piwik.php']); - _paq.push(['setSiteId', 9]); - var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0]; - g.type='text/javascript'; g.async=true; g.defer=true; g.src=u+'piwik.js'; s.parentNode.insertBefore(g,s); - })(); %noscript %p %img{:alt => "", :src => "//stat.rrerr.net/piwik.php?idsite=9", :style => "border:0;"}/ diff --git a/app/views/notifications/_notification.html.haml b/app/views/notifications/_notification.html.haml new file mode 100644 index 00000000..00fb1ccb --- /dev/null +++ b/app/views/notifications/_notification.html.haml @@ -0,0 +1,57 @@ +%li.list-group-item{class: (notification.new? ? 'list-group-item-warning' : '')} + .media + - case notification.target_type + - when "Answer" + .pull-left + %img.img-rounded.notification--img{src: gravatar_url(notification.target.user)} + .media-body + %h6.media-heading.notification--user + = user_screen_name notification.target.user + %p.notification--text + answered + %a{href: show_user_answer_path(username: notification.target.user.screen_name, id: notification.target.id), title: "#{notification.target.content[0..40]}...", data: { toggle: :tooltip, placement: :top }} + your question + = time_ago_in_words notification.target.created_at + ago + .notification--icon + %i.fa.fa-exclamation + - when "Relationship" + .pull-left + %img.img-rounded.notification--img{src: gravatar_url(notification.target.source)} + .media-body + %h6.media-heading.notification--user + = user_screen_name notification.target.source + %p.notification--text + followed you + = time_ago_in_words notification.target.created_at + ago + .notification--icon + %i.fa.fa-users + - when "Smile" + .pull-left + %img.img-rounded.notification--img{src: gravatar_url(notification.target.user)} + .media-body + %h6.media-heading.notification--user + = user_screen_name notification.target.user + %p.notification--text + smiled at + %a{href: show_user_answer_path(username: notification.target.user.screen_name, id: notification.target.answer.id), title: "#{notification.target.answer.content[0..40]}...", data: { toggle: :tooltip, placement: :top }} + your answer + = time_ago_in_words notification.target.created_at + ago + .notification--icon + %i.fa.fa-smile-o + - when "Comment" + .pull-left + %img.img-rounded.notification--img{src: gravatar_url(notification.target.user)} + .media-body + %h6.media-heading.notification--user + = user_screen_name notification.target.user + %p.notification--text + commented on + %a{href: show_user_answer_path(username: notification.target.user.screen_name, id: notification.target.answer.id), title: "#{notification.target.answer.content[0..40]}...", data: { toggle: :tooltip, placement: :top }} + your answer + = time_ago_in_words notification.target.created_at + ago + .notification--icon + %i.fa.fa-comments \ No newline at end of file diff --git a/app/views/notifications/index.html.haml b/app/views/notifications/index.html.haml index 919de1c4..348a6c98 100644 --- a/app/views/notifications/index.html.haml +++ b/app/views/notifications/index.html.haml @@ -1,63 +1,13 @@ .container.j2-page = render 'notification_tabs' .col-md-9.col-xs-12.col-sm-9 - %ul.list-group + %ul#notifications.list-group - @notifications.each do |notification| - %li.list-group-item{class: (notification.new? ? 'list-group-item-warning' : '')} - .media - - case notification.target_type - - when "Answer" - .pull-left - %img.img-rounded.notification--img{src: gravatar_url(notification.target.user)} - .media-body - %h6.media-heading.notification--user - = user_screen_name notification.target.user - %p.notification--text - answered - %a{href: show_user_answer_path(username: notification.target.user.screen_name, id: notification.target.id), title: "#{notification.target.content[0..40]}...", data: { toggle: :tooltip, placement: :top }} - your question - = time_ago_in_words notification.target.created_at - ago - .notification--icon - %i.fa.fa-exclamation - - when "Relationship" - .pull-left - %img.img-rounded.notification--img{src: gravatar_url(notification.target.source)} - .media-body - %h6.media-heading.notification--user - = user_screen_name notification.target.source - %p.notification--text - followed you - = time_ago_in_words notification.target.created_at - ago - .notification--icon - %i.fa.fa-users - - when "Smile" - .pull-left - %img.img-rounded.notification--img{src: gravatar_url(notification.target.user)} - .media-body - %h6.media-heading.notification--user - = user_screen_name notification.target.user - %p.notification--text - smiled at - %a{href: show_user_answer_path(username: notification.target.user.screen_name, id: notification.target.answer.id), title: "#{notification.target.answer.content[0..40]}...", data: { toggle: :tooltip, placement: :top }} - your answer - = time_ago_in_words notification.target.created_at - ago - .notification--icon - %i.fa.fa-smile-o - - when "Comment" - .pull-left - %img.img-rounded.notification--img{src: gravatar_url(notification.target.user)} - .media-body - %h6.media-heading.notification--user - = user_screen_name notification.target.user - %p.notification--text - commented on - %a{href: show_user_answer_path(username: notification.target.user.screen_name, id: notification.target.answer.id), title: "#{notification.target.answer.content[0..40]}...", data: { toggle: :tooltip, placement: :top }} - your answer - = time_ago_in_words notification.target.created_at - ago - .notification--icon - %i.fa.fa-comments + = render 'notifications/notification', notification: notification + + #pagination= will_paginate @notifications, renderer: BootstrapPagination::Rails, page_links: false + + - if @notifications.next_page + %button#load-more-btn.btn.btn-default{type: :button, data: { current_page: @notifications.current_page }} + Load more - Notification.for(current_user).update_all(new: false) \ No newline at end of file diff --git a/app/views/notifications/index.js.erb b/app/views/notifications/index.js.erb new file mode 100644 index 00000000..f3f5bd18 --- /dev/null +++ b/app/views/notifications/index.js.erb @@ -0,0 +1,8 @@ +$('#notifications').append('<% @notifications.each do |notification| + %><%= j render 'notifications/notification', notification: notification +%><% end %>'); +<% if @notifications.next_page %> + $('#pagination').html('<%= j will_paginate @notifications, renderer: BootstrapPagination::Rails, page_links: false %>'); +<% else %> + $('#pagination, #load-more-btn').remove(); +<% end %> \ No newline at end of file diff --git a/app/views/shared/_answerbox.html.haml b/app/views/shared/_answerbox.html.haml index fc24adae..e486e8fc 100644 --- a/app/views/shared/_answerbox.html.haml +++ b/app/views/shared/_answerbox.html.haml @@ -20,18 +20,20 @@ · %a{href: show_user_question_path(a.question.user.screen_name, a.question.id)} #{a.question.answer_count} answers - %p.answerbox--question-text + .answerbox--question-text = a.question.content .panel-body - if @display_all.nil? - = markdown a.content[0..255] - - if a.content.length > 255 - [...] - %p - %a.btn.btn-primary{href: show_user_answer_path(a.user.screen_name, a.id)} - Read the entire answer + .answerbox--answer-text + = markdown a.content[0..255] + - if a.content.length > 255 + [...] + %p + %a.btn.btn-primary{href: show_user_answer_path(a.user.screen_name, a.id)} + Read the entire answer - else - = markdown a.content + .answerbox--answer-text + = markdown a.content - if @user.nil? .row .col-md-6.col-sm-4.col-xs-7.text-left.text-muted diff --git a/app/views/shared/_questionbox.html.haml b/app/views/shared/_questionbox.html.haml index 89bceb2d..34c79e0a 100644 --- a/app/views/shared/_questionbox.html.haml +++ b/app/views/shared/_questionbox.html.haml @@ -6,47 +6,52 @@ - else = @user.motivation_header .panel-body - - if user_signed_in? or @user.privacy_allow_anonymous_questions? - #question-box - .row - .col-xs-12 - %textarea.form-control{:name => "qb-question", :placeholder => "Type your question here…"} - .row{:style => "padding-top: 5px; padding-left: 5px; padding-right: 5px;"} - .col-xs-6 - - if user_signed_in? - - if @user.privacy_allow_anonymous_questions? - %input{:name => "qb-anonymous", :type => "checkbox"}/ - Hide your name - %br/ - - else - %input{:name => "qb-anonymous", :type => "hidden", :value => "false"}/ - .col-xs-6 - %p.pull-right - %input{name: 'qb-to', type: 'hidden', :value => @user.id}/ - %button.btn.btn-primary{name: 'qb-ask', :type => "button", data: {loading_text: 'Asking...', promote: user_signed_in? ? "false" : "true" }} Ask - - unless user_signed_in? - - if @user.privacy_allow_anonymous_questions? - #question-box-promote.row{:style => "display: none;"} + - if @user.banned? + .row + .col-xs-12.text-center + %strong This user got hit with ye olde banhammer. + - else + - if user_signed_in? or @user.privacy_allow_anonymous_questions? + #question-box .row - .col-xs-12.text-center - %strong Your question has been sent. - .row - .col-sm-1 - .col-sm-5 - %button#create-account.btn.btn-block.btn-primary Create an account - .col-sm-5 - %button#new-question.btn.btn-block.btn-default Ask another question - .col-sm-1 - .row - .col-sm-1 - .col-xs-12.col-sm-10 - %small - Join - = APP_CONFIG['site_name'] - today! You'll be able to follow and ask people you know and a lot more. - .col-sm-1 - - else - %p - This user does not want to get asked by strangers. Why don't you - = succeed "?" do - %a{:href => "{{ url_for('register') }}"} sign up \ No newline at end of file + .col-xs-12 + %textarea.form-control{:name => "qb-question", :placeholder => "Type your question here…"} + .row{:style => "padding-top: 5px; padding-left: 5px; padding-right: 5px;"} + .col-xs-6 + - if user_signed_in? + - if @user.privacy_allow_anonymous_questions? + %input{:name => "qb-anonymous", :type => "checkbox"}/ + Hide your name + %br/ + - else + %input{:name => "qb-anonymous", :type => "hidden", :value => "false"}/ + .col-xs-6 + %p.pull-right + %input{name: 'qb-to', type: 'hidden', :value => @user.id}/ + %button.btn.btn-primary{name: 'qb-ask', :type => "button", data: {loading_text: 'Asking...', promote: user_signed_in? ? "false" : "true" }} Ask + - unless user_signed_in? + - if @user.privacy_allow_anonymous_questions? + #question-box-promote.row{:style => "display: none;"} + .row + .col-xs-12.text-center + %strong Your question has been sent. + .row + .col-sm-1 + .col-sm-5 + %button#create-account.btn.btn-block.btn-primary Create an account + .col-sm-5 + %button#new-question.btn.btn-block.btn-default Ask another question + .col-sm-1 + .row + .col-sm-1 + .col-xs-12.col-sm-10 + %small + Join + = APP_CONFIG['site_name'] + today! You'll be able to follow and ask people you know and a lot more. + .col-sm-1 + - else + %p + This user does not want to get asked by strangers. Why don't you + = succeed "?" do + %a{:href => "{{ url_for('register') }}"} sign up \ No newline at end of file diff --git a/app/views/static/about.html.haml b/app/views/static/about.html.haml index da678da8..b2ad025e 100644 --- a/app/views/static/about.html.haml +++ b/app/views/static/about.html.haml @@ -106,9 +106,7 @@ People that believe in our vision, and that's why we love them <3 %ul.about--moderator - User.where(supporter: true).each do |sup| - %li - %a{href: show_user_profile_path(sup.screen_name)} - %img.answerbox--img-small{src: User.find_by_screen_name(sup.screen_name).profile_picture.url(:medium)} - = sup.screen_name + %a{href: show_user_profile_path(sup.screen_name), title: sup.screen_name, data: { toggle: :tooltip, placement: :top }} + %img.img-rounded.answerbox--img-small{src: sup.profile_picture.url(:medium)} = render "shared/links" diff --git a/app/views/user/_profile_info.html.haml b/app/views/user/_profile_info.html.haml index 01b60fb2..dc310f11 100644 --- a/app/views/user/_profile_info.html.haml +++ b/app/views/user/_profile_info.html.haml @@ -12,6 +12,10 @@ .profile--panel-badge.panel-badge-warning %i.fa.fa-star Supporter + - if @user.banned? + .profile--panel-badge.panel-badge-default + %i.fa.fa-ban + Banned - if @user.following? current_user .profile--panel-badge.panel-badge-default Follows you diff --git a/config/application.rb b/config/application.rb index 21270043..e30ee771 100644 --- a/config/application.rb +++ b/config/application.rb @@ -19,5 +19,6 @@ module Justask # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded. # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s] # config.i18n.default_locale = :de + config.autoload_paths += %W["#{config.root}/app/validators"] end end diff --git a/config/initializers/omniauth.rb b/config/initializers/omniauth.rb index ba7ec8bc..61a34a79 100644 --- a/config/initializers/omniauth.rb +++ b/config/initializers/omniauth.rb @@ -1,5 +1,7 @@ Rails.application.config.middleware.use OmniAuth::Builder do - if APP_CONFIG['sharing']['twitter']['enabled'] - provider :twitter, APP_CONFIG['sharing']['twitter']['consumer_key'], APP_CONFIG['sharing']['twitter']['consumer_secret'] + %w(facebook twitter tumblr).each do |service| + if APP_CONFIG['sharing'][service]['enabled'] + provider service.to_sym, APP_CONFIG['sharing'][service]['consumer_key'], APP_CONFIG['sharing'][service]['consumer_secret'] + end end end \ No newline at end of file diff --git a/config/initializers/rails_admin.rb b/config/initializers/rails_admin.rb index 49048511..3f5b7408 100644 --- a/config/initializers/rails_admin.rb +++ b/config/initializers/rails_admin.rb @@ -41,6 +41,7 @@ RailsAdmin.config do |config| Report Service Services::Twitter + Services::Tumblr Smile User ] diff --git a/config/initializers/redcarpet.rb b/config/initializers/redcarpet.rb new file mode 100644 index 00000000..86df114b --- /dev/null +++ b/config/initializers/redcarpet.rb @@ -0,0 +1,18 @@ +require 'redcarpet/render_strip' + +MARKDOWN_OPTS = { + filter_html: true, + escape_html: true, + no_images: true, + no_styles: true, + safe_links_only: true, + xhtml: false, + hard_wrap: true, + no_intra_emphasis: true, + tables: true, + fenced_code_blocks: true, + autolink: true, + disable_indented_code_blocks: true, + strikethrough: true, + superscript: false +} \ No newline at end of file diff --git a/config/justask.yml.example b/config/justask.yml.example index d2f26741..b5a5cf72 100644 --- a/config/justask.yml.example +++ b/config/justask.yml.example @@ -21,6 +21,11 @@ sharing: consumer_secret: '' facebook: enabled: false + tumblr: + enabled: true + # Get the tokens from https://www.tumblr.com/oauth/apps + consumer_key: '' + consumer_secret: '' # Redis redis_url: "redis://localhost:6379" \ No newline at end of file diff --git a/db/migrate/20150112210754_add_banned_to_users.rb b/db/migrate/20150112210754_add_banned_to_users.rb new file mode 100644 index 00000000..6b7c65b7 --- /dev/null +++ b/db/migrate/20150112210754_add_banned_to_users.rb @@ -0,0 +1,5 @@ +class AddBannedToUsers < ActiveRecord::Migration + def change + add_column :users, :banned, :boolean, default: false + end +end diff --git a/db/migrate/20150108121010_create_groups.rb b/db/migrate/20150112210755_create_groups.rb similarity index 100% rename from db/migrate/20150108121010_create_groups.rb rename to db/migrate/20150112210755_create_groups.rb diff --git a/db/schema.rb b/db/schema.rb index 4a23f1b5..42159d46 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20150108121010) do +ActiveRecord::Schema.define(version: 20150112210755) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -197,6 +197,7 @@ ActiveRecord::Schema.define(version: 20150108121010) do t.boolean "privacy_allow_public_timeline", default: true t.boolean "privacy_allow_stranger_answers", default: true t.boolean "privacy_show_in_search", default: true + t.boolean "banned", default: false end add_index "users", ["email"], name: "index_users_on_email", unique: true, using: :btree diff --git a/public/apple-touch-icon-precomposed.png b/public/apple-touch-icon-precomposed.png new file mode 100644 index 00000000..37b95a49 Binary files /dev/null and b/public/apple-touch-icon-precomposed.png differ diff --git a/public/apple-touch-icon.png b/public/apple-touch-icon.png deleted file mode 100644 index 7d16acd5..00000000 Binary files a/public/apple-touch-icon.png and /dev/null differ diff --git a/public/favicon.ico b/public/favicon.ico index dd5dc0cd..4bfcccfd 100644 Binary files a/public/favicon.ico and b/public/favicon.ico differ diff --git a/public/icon-152.png b/public/icon-152.png new file mode 100644 index 00000000..37b95a49 Binary files /dev/null and b/public/icon-152.png differ diff --git a/public/images/favicon/favicon-16.png b/public/images/favicon/favicon-16.png new file mode 100644 index 00000000..808d80e5 Binary files /dev/null and b/public/images/favicon/favicon-16.png differ diff --git a/public/images/favicon/favicon-32.png b/public/images/favicon/favicon-32.png new file mode 100644 index 00000000..7564eb66 Binary files /dev/null and b/public/images/favicon/favicon-32.png differ