summaryrefslogtreecommitdiff
path: root/lib/aggiedit/rooms.ex
blob: 898dfe12a90584a3bae3e9fd228bc19b2f1c34d7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
defmodule Aggiedit.Rooms do
  @moduledoc """
  The Rooms context.
  """

  import Ecto.Query, warn: false
  alias Aggiedit.Repo

  alias Aggiedit.Accounts
  alias Aggiedit.Rooms.Room

  alias Phoenix.PubSub

  def list_rooms do
    Repo.all(Room)
  end

  def get_room!(id), do: Repo.get!(Room, id)

  def create_room(attrs \\ %{}) do
    %Room{}
    |> Room.changeset(attrs)
    |> Repo.insert()
  end

  def update_room(%Room{} = room, attrs) do
    room
    |> Room.changeset(attrs)
    |> Repo.update()
  end

  def delete_room(%Room{} = room) do
    Repo.delete(room)
  end

  def change_room(%Room{} = room, attrs \\ %{}) do
    Room.changeset(room, attrs)
  end

  def create_or_find_room_with_domain(domain) do
    case Repo.get_by(Room, domain: domain) do
      room=%Room{} -> {:ok, room}
      nil -> create_room(%{domain: domain})
    end
  end

  alias Aggiedit.Rooms.Post

  def list_posts do
    Repo.all(Post)
  end

  def posts_in_room(room_id) do
    Repo.all((from p in Post, where: p.room_id == ^room_id, order_by: [asc: :id], select: p))
  end

  def get_post!(id), do: Repo.get!(Post, id)

  def create_post(attrs, user, after_save \\ &{:ok, &1}) do
    user = Repo.preload(user, :room)

    %Post{}
    |> Repo.preload([:user, :room])
    |> Post.changeset(attrs)
    |> Ecto.Changeset.put_assoc(:user, user)
    |> Ecto.Changeset.put_assoc(:room, user.room)
    |> Repo.insert()
    |> broadcast_post_over_room(:post_created)
    |> post_saved(after_save)
  end

  def update_post(%Post{} = post, attrs, after_save \\ &{:ok, &1}) do
    post
    |> Post.changeset(attrs)
    |> Repo.update()
    |> broadcast_post_over_room(:post_updated)
    |> post_saved(after_save)
  end

  defp post_saved({:ok, post}, func) do
    {:ok, _post} = func.(post)
  end
  defp post_saved(error, _fun), do: error

  def delete_post(%Post{} = post) do
    Repo.delete(post)
    |> broadcast_post_over_room(:post_deleted)
  end

  def change_post(%Post{} = post, attrs \\ %{}) do
    Post.changeset(post, attrs)
  end

  defp broadcast_post_over_room({:error, _reason}=error, _event), do: error
  defp broadcast_post_over_room({:ok, post}, event) do 
    PubSub.broadcast(Aggiedit.PubSub, "room:#{post.room_id}:posts", {event, post})
    {:ok, post}
  end

  def subscribe(room) do
    PubSub.subscribe(Aggiedit.PubSub, "room:#{room.id}:posts")
  end
end