Merge pull request #11 from skiprope/subscriptions
Support for post subscriptions
This commit is contained in:
commit
2992cba387
56
Rakefile
56
Rakefile
|
@ -198,6 +198,45 @@ namespace :justask do
|
|||
puts "Purged #{destroyed_count} dead notifications."
|
||||
end
|
||||
|
||||
desc "Subscribes everyone to their answers"
|
||||
task fix_submarines: :enviornment do
|
||||
format = '%t (%c/%C) [%b>%i] %e'
|
||||
|
||||
total = Answer.count
|
||||
progress = ProgressBar.create title: 'Processing answers', format: format, starting_at: 0, total: total
|
||||
subscribed = 0
|
||||
|
||||
Answer.all.each do |a|
|
||||
if not s.user.nil? and not s.answer.nil?
|
||||
Subscription.subscribe a.user, a
|
||||
subscribed += 1
|
||||
end
|
||||
|
||||
progress.increment
|
||||
end
|
||||
|
||||
puts "Subscribed to #{subscribed} posts."
|
||||
end
|
||||
|
||||
desc "Destroy lost subscriptions"
|
||||
task fix_torpedoes: :enviornment do
|
||||
format = '%t (%c/%C) [%b>%i] %e'
|
||||
|
||||
total = Subscription.count
|
||||
progress = ProgressBar.create title: 'Processing subscriptions', format: format, starting_at: 0, total: total
|
||||
destroyed = 0
|
||||
Subscription.all.each do |s|
|
||||
if s.user.nil? or s.answer.nil?
|
||||
s.destroy
|
||||
destroyed += 1
|
||||
end
|
||||
|
||||
progress.increment
|
||||
end
|
||||
|
||||
puts "Put #{destroyed} subscriptions up for adoption."
|
||||
end
|
||||
|
||||
desc "Fixes everything else"
|
||||
task fix_db: :environment do
|
||||
format = '%t (%c/%C) [%b>%i] %e'
|
||||
|
@ -206,7 +245,8 @@ namespace :justask do
|
|||
question: 0,
|
||||
answer: 0,
|
||||
smile: 0,
|
||||
comment: 0
|
||||
comment: 0,
|
||||
subscription: 0
|
||||
}
|
||||
|
||||
total = Inbox.count
|
||||
|
@ -250,10 +290,24 @@ namespace :justask do
|
|||
progress.increment
|
||||
end
|
||||
|
||||
total = Subscription.count
|
||||
progress = ProgressBar.create title: 'Processing subscriptions', format: format, starting_at: 0, total: total
|
||||
Subscription.all.each do |s|
|
||||
if s.user.nil? or s.answer.nil?
|
||||
s.destroy
|
||||
destroyed_count[:subscription] += 1
|
||||
end
|
||||
|
||||
progress.increment
|
||||
end
|
||||
|
||||
puts "Put #{destroyed} subscriptions up for adoption."
|
||||
|
||||
puts "Purged #{destroyed_count[:inbox]} dead inbox entries."
|
||||
puts "Marked #{destroyed_count[:question]} questions as anonymous."
|
||||
puts "Purged #{destroyed_count[:answer]} dead answers."
|
||||
puts "Purged #{destroyed_count[:answer]} dead comments."
|
||||
puts "Purged #{destroyed_count[:subscription]} dead subscriptions."
|
||||
end
|
||||
|
||||
desc "Prints lonely people."
|
||||
|
|
|
@ -39,6 +39,9 @@ $(document).on "keyup", "input[name=ab-comment-new]", (evt) ->
|
|||
input.val ''
|
||||
ctr.html 160
|
||||
$("span#ab-comment-count-#{aid}").html data.count
|
||||
subs = $("a[data-action=ab-submarine][data-a-id=#{aid}]")[0]
|
||||
subs.dataset.torpedo = "no"
|
||||
subs.children[0].nextSibling.textContent = "Unsubscribe"
|
||||
showNotification data.message, data.success
|
||||
error: (jqxhr, status, error) ->
|
||||
console.log jqxhr, status, error
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
# the laziest coding known to man
|
||||
$(document).on "click", "a[data-action=ab-submarine]", (ev) ->
|
||||
ev.preventDefault()
|
||||
btn = $(this)
|
||||
aid = btn[0].dataset.aId
|
||||
torpedo = 0
|
||||
if btn[0].dataset.torpedo == "yes"
|
||||
torpedo = 1
|
||||
endpoint = "subscribe"
|
||||
if torpedo == 0
|
||||
endpoint = "un" + endpoint
|
||||
$.ajax
|
||||
url: '/ajax/' + endpoint # TODO: find a way to use rake routes instead of hardcoding them here
|
||||
type: 'POST'
|
||||
data:
|
||||
answer: aid
|
||||
success: (data, status, jqxhr) ->
|
||||
if data.success
|
||||
btn[0].dataset.torpedo = ["yes", "no"][torpedo]
|
||||
btn[0].children[0].nextSibling.textContent = ["Subscribe", "Unsubscribe"][torpedo]
|
||||
showNotification "Successfully " + endpoint + "d.", true
|
||||
else
|
||||
showNotification "Couldn't unsubscribe from the answer.", false
|
||||
error: (jqxhr, status, error) ->
|
||||
console.log jqxhr, status, error
|
||||
showNotification "An error occurred, a developer should check the console for details", false
|
||||
complete: (jqxhr, status) ->
|
|
@ -0,0 +1,19 @@
|
|||
class Ajax::SubscriptionController < ApplicationController
|
||||
before_filter :authenticate_user!
|
||||
|
||||
def subscribe
|
||||
params.require :answer
|
||||
@status = 418
|
||||
@message = "418 I'm a torpedo"
|
||||
state = Subscription.subscribe(current_user, Answer.find(params[:answer])).nil?
|
||||
@success = state == false
|
||||
end
|
||||
|
||||
def unsubscribe
|
||||
params.require :answer
|
||||
@status = 418
|
||||
@message = "418 I'm a torpedo"
|
||||
state = Subscription.unsubscribe(current_user, Answer.find(params[:answer])).nil?
|
||||
@success = state == false
|
||||
end
|
||||
end
|
|
@ -0,0 +1,2 @@
|
|||
module SubscribeHelper
|
||||
end
|
|
@ -3,11 +3,14 @@ class Answer < ActiveRecord::Base
|
|||
belongs_to :question
|
||||
has_many :comments, dependent: :destroy
|
||||
has_many :smiles, dependent: :destroy
|
||||
has_many :subscriptions, dependent: :destroy
|
||||
|
||||
after_create do
|
||||
Inbox.where(user: self.user, question: self.question).destroy_all
|
||||
|
||||
Notification.notify self.question.user, self unless self.question.author_is_anonymous
|
||||
Subscription.subscribe self.user, self
|
||||
Subscription.subscribe self.question.user, self
|
||||
self.user.increment! :answered_count
|
||||
self.question.increment! :answer_count
|
||||
end
|
||||
|
@ -27,9 +30,10 @@ class Answer < ActiveRecord::Base
|
|||
end
|
||||
self.comments.each do |comment|
|
||||
comment.user.decrement! :commented_count
|
||||
Notification.denotify self.user, comment
|
||||
Subscription.denotify comment, self
|
||||
end
|
||||
Notification.denotify self.question.user, self
|
||||
Subscription.destruct self
|
||||
end
|
||||
|
||||
def notification_type(*_args)
|
||||
|
|
|
@ -7,14 +7,15 @@ class Comment < ActiveRecord::Base
|
|||
validates :content, length: { maximum: 160 }
|
||||
|
||||
after_create do
|
||||
Notification.notify answer.user, self unless answer.user == self.user
|
||||
Subscription.subscribe self.user, answer, false
|
||||
Subscription.notify self, answer
|
||||
user.increment! :commented_count
|
||||
answer.increment! :comment_count
|
||||
end
|
||||
|
||||
before_destroy do
|
||||
Notification.denotify answer.user, self unless answer.user == self.user
|
||||
user.decrement! :commented_count
|
||||
Subscription.denotify self, answer
|
||||
user.decrement! :commented_count
|
||||
answer.decrement! :comment_count
|
||||
end
|
||||
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
class Subscription < ActiveRecord::Base
|
||||
belongs_to :user
|
||||
belongs_to :answer
|
||||
|
||||
class << self
|
||||
def for(target)
|
||||
Subscription.where(answer: target)
|
||||
end
|
||||
|
||||
def is_subscribed(recipient, target)
|
||||
existing = Subscription.find_by(user: recipient, answer: target)
|
||||
existing.nil? or existing.is_active
|
||||
end
|
||||
|
||||
def subscribe(recipient, target, force = true)
|
||||
existing = Subscription.find_by(user: recipient, answer: target)
|
||||
if existing.nil?
|
||||
Subscription.new(user: recipient, answer: target).save!
|
||||
elsif force
|
||||
existing.update(is_active: true)
|
||||
end
|
||||
end
|
||||
|
||||
def unsubscribe(recipient, target)
|
||||
if recipient.nil? or target.nil?
|
||||
return nil
|
||||
end
|
||||
|
||||
subs = Subscription.find_by(user: recipient, answer: target)
|
||||
subs.update(is_active: false) unless subs.nil?
|
||||
end
|
||||
|
||||
def destruct(target)
|
||||
if target.nil?
|
||||
return nil
|
||||
end
|
||||
Subscription.where(answer: target).destroy_all
|
||||
end
|
||||
|
||||
def destruct_by(recipient, target)
|
||||
if recipient.nil? or target.nil?
|
||||
return nil
|
||||
end
|
||||
|
||||
subs = Subscription.find_by(user: recipient, answer: target)
|
||||
subs.destroy unless subs.nil?
|
||||
end
|
||||
|
||||
def notify(source, target)
|
||||
if source.nil? or target.nil?
|
||||
return nil
|
||||
end
|
||||
|
||||
Subscription.where(answer: target, is_active: true).each do |subs|
|
||||
next unless not subs.user == source.user
|
||||
Notification.notify subs.user, source
|
||||
end
|
||||
end
|
||||
|
||||
def denotify(source, target)
|
||||
if source.nil? or target.nil?
|
||||
return nil
|
||||
end
|
||||
Subscription.where(answer: target).each do |subs|
|
||||
Notification.denotify subs.user, source
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -28,6 +28,8 @@ class User < ActiveRecord::Base
|
|||
has_many :groups, dependent: :destroy
|
||||
has_many :group_memberships, class_name: "GroupMember", foreign_key: 'user_id', dependent: :destroy
|
||||
|
||||
has_many :subscriptions, dependent: :destroy
|
||||
|
||||
SCREEN_NAME_REGEX = /\A[a-zA-Z0-9_]{1,16}\z/
|
||||
WEBSITE_REGEX = /https?:\/\/([A-Za-z.\-]+)\/?(?:.*)/i
|
||||
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
json.partial! 'ajax/shared/status'
|
|
@ -0,0 +1 @@
|
|||
json.partial! 'ajax/shared/status'
|
|
@ -53,7 +53,13 @@
|
|||
%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
|
||||
- if notification.target.answer.user == current_user
|
||||
your
|
||||
- elsif notification.target.user == notification.target.answer.user
|
||||
their
|
||||
- else
|
||||
= user_screen_name(notification.target.answer.user, false, false) + "'s"
|
||||
answer
|
||||
%span{title: notification.target.created_at, data: { toggle: :tooltip, placement: :bottom }}
|
||||
= time_ago_in_words notification.target.created_at
|
||||
ago
|
||||
|
|
|
@ -21,6 +21,17 @@
|
|||
%button.btn.btn-default.btn-sm.dropdown-toggle{data: { toggle: :dropdown }, aria: { expanded: :false }}
|
||||
%span.caret
|
||||
%ul.dropdown-menu.dropdown-menu-right{role: :menu}
|
||||
- if Subscription.is_subscribed(current_user, a)
|
||||
%li
|
||||
-# fun joke should subscribe?
|
||||
%a{href: '#', data: { a_id: a.id, action: 'ab-submarine', torpedo: "no" }}
|
||||
%i.fa.fa-anchor
|
||||
Unubscribe
|
||||
- else
|
||||
%li
|
||||
%a{href: '#', data: { a_id: a.id, action: 'ab-submarine', torpedo: "yes" }}
|
||||
%i.fa.fa-anchor
|
||||
Subscribe
|
||||
- if privileged? a.user
|
||||
%li.text-danger
|
||||
%a{href: '#', data: { a_id: a.id, action: 'ab-destroy' }}
|
||||
|
|
|
@ -82,6 +82,8 @@ Rails.application.routes.draw do
|
|||
match '/destroy_group', to: 'group#destroy', via: :post, as: :destroy_group
|
||||
match '/group_membership', to: 'group#membership', via: :post, as: :group_membership
|
||||
match '/preview', to: "question#preview", via: :post, as: :preview
|
||||
match '/subscribe', to: 'subscription#subscribe', via: :post, as: :subscribe_answer
|
||||
match '/unsubscribe', to: 'subscription#unsubscribe', via: :post, as: :unsubscribe_answer
|
||||
end
|
||||
|
||||
match '/public', to: 'public#index', via: :get, as: :public_timeline
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
class CreateSubscriptions < ActiveRecord::Migration
|
||||
def change
|
||||
create_table :subscriptions do |t|
|
||||
t.integer :user_id, null: false
|
||||
t.integer :answer_id, null: false
|
||||
|
||||
t.timestamps null: false
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,5 @@
|
|||
class AddIsActiveToSubscriptions < ActiveRecord::Migration
|
||||
def change
|
||||
add_column :subscriptions, :is_active, :boolean, default: :true
|
||||
end
|
||||
end
|
|
@ -0,0 +1,5 @@
|
|||
require 'rails_helper'
|
||||
|
||||
RSpec.describe SubscribeController, :type => :controller do
|
||||
|
||||
end
|
|
@ -0,0 +1,15 @@
|
|||
require 'rails_helper'
|
||||
|
||||
# Specs in this file have access to a helper object that includes
|
||||
# the SubscribeHelper. For example:
|
||||
#
|
||||
# describe SubscribeHelper do
|
||||
# describe "string concat" do
|
||||
# it "concats two strings with spaces" do
|
||||
# expect(helper.concat_strings("this","that")).to eq("this that")
|
||||
# end
|
||||
# end
|
||||
# end
|
||||
RSpec.describe SubscribeHelper, :type => :helper do
|
||||
pending "add some examples to (or delete) #{__FILE__}"
|
||||
end
|
|
@ -0,0 +1,5 @@
|
|||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Subscription, :type => :model do
|
||||
pending "add some examples to (or delete) #{__FILE__}"
|
||||
end
|
Loading…
Reference in New Issue