diff --git a/lib/myapp/data/reply.ex b/lib/myapp/data/reply.ex index e1db8bc..dfd5c13 100644 --- a/lib/myapp/data/reply.ex +++ b/lib/myapp/data/reply.ex @@ -44,7 +44,7 @@ defmodule MyApp.Data.Reply do thread_id = Map.get(reply, :thread_id) user_id = Map.get(reply, :user_id) query = from t in Data.Thread, where: t.id == ^thread_id, - update: [set: [last_reply_id: ^user_id], inc: [reply_count: 1]] + update: [set: [last_reply_id: ^user_id, updated_at: ^DateTime.utc_now], inc: [reply_count: 1]] case Repo.update_all(query, []) do nil -> {:error, "update thread error"} diff --git a/lib/myapp/data/thread.ex b/lib/myapp/data/thread.ex index d2f0c30..52c244b 100644 --- a/lib/myapp/data/thread.ex +++ b/lib/myapp/data/thread.ex @@ -110,6 +110,14 @@ defmodule MyApp.Data.Thread do end end + # this doesn't update the 'updated_at' field which is what we want + def update_view_count(thread_id) do + query = from t in Data.Thread, + update: [inc: [view_count: 1]], + where: t.id == ^thread_id + Repo.update_all(query, []) + end + # TODO: delete thread defp process_user_update(thread, _params) when is_nil(thread), do: {:error, "Invalid thread"} diff --git a/lib/myapp/view_counter.ex b/lib/myapp/view_counter.ex new file mode 100644 index 0000000..065e6fc --- /dev/null +++ b/lib/myapp/view_counter.ex @@ -0,0 +1,20 @@ +defmodule MyApp.ViewCounter do + alias MyApp.Data + + # cache end points for 5 minutes based on the browser fingerprint + + @spec thread_view_count(String.t, integer) :: {:error, String.t} | {any, boolean} + def thread_view_count(fingerprint, thread_id) do + + key = "#{fingerprint}:#{thread_id}" + + case Cachex.get(:myapp, key) do + {:ok, _} -> {:error, "Already viewed."} + {:missing, _} -> + {1, nil} = Data.Thread.update_view_count(thread_id) + Cachex.set(:myapp, key, true, ttl: :timer.minutes(5)) + end + + end + +end diff --git a/lib/myapp_web/controllers/thread_controller.ex b/lib/myapp_web/controllers/thread_controller.ex index d58754c..fd74616 100644 --- a/lib/myapp_web/controllers/thread_controller.ex +++ b/lib/myapp_web/controllers/thread_controller.ex @@ -50,7 +50,14 @@ defmodule MyAppWeb.ThreadController do @spec get(map, map) :: any def get(conn, params) do - {output, status} = params["id"] + fingerprint = get_req_header(conn, "fp") + thread_id = params["id"] + + spawn fn -> + MyApp.ViewCounter.thread_view_count(fingerprint, thread_id) + end + + {output, status} = thread_id |> Data.Thread.get |> Response.put_resp