Show current visitors
This commit is contained in:
parent
9868392818
commit
00d02faad0
|
|
@ -125,4 +125,13 @@ if (domainEl) {
|
|||
router.updateLinkHandlers()
|
||||
})
|
||||
})
|
||||
|
||||
setInterval(function() {
|
||||
fetch(`/api/${domain}/current-visitors`)
|
||||
.then(res => res.json())
|
||||
.then((res) => {
|
||||
console.log(res)
|
||||
document.getElementById('current-visitors').innerHTML = res
|
||||
})
|
||||
}, 10000)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -181,6 +181,15 @@ defmodule Plausible.Stats do
|
|||
)
|
||||
end
|
||||
|
||||
def current_visitors(site) do
|
||||
Repo.one(
|
||||
from p in Plausible.Pageview,
|
||||
where: p.inserted_at >= fragment("(now() at time zone 'utc') - '5 minutes'::interval"),
|
||||
where: p.hostname == ^site.domain,
|
||||
select: count(p.user_id, :distinct)
|
||||
)
|
||||
end
|
||||
|
||||
defp base_query(site, query) do
|
||||
{:ok, first} = NaiveDateTime.new(query.date_range.first, ~T[00:00:00])
|
||||
first_datetime = Timex.to_datetime(first, site.timezone)
|
||||
|
|
|
|||
|
|
@ -23,12 +23,14 @@ defmodule PlausibleWeb.StatsController do
|
|||
|
||||
{conn, params} = fetch_period(conn, site)
|
||||
query = Stats.Query.from(site.timezone, params)
|
||||
current_visitors = Stats.current_visitors(site)
|
||||
|
||||
conn
|
||||
|> assign(:skip_plausible_tracking, !demo)
|
||||
|> render("stats.html",
|
||||
site: site,
|
||||
query: query,
|
||||
current_visitors: current_visitors,
|
||||
title: "Plausible · " <> site.domain
|
||||
)
|
||||
else
|
||||
|
|
@ -295,6 +297,16 @@ defmodule PlausibleWeb.StatsController do
|
|||
end
|
||||
end
|
||||
|
||||
def current_visitors(conn, %{"domain" => domain}) do
|
||||
site = Repo.get_by(Plausible.Site, domain: domain)
|
||||
|
||||
if site && current_user_can_access?(conn, site) do
|
||||
json(conn, Stats.current_visitors(site))
|
||||
else
|
||||
render_error(conn, 404)
|
||||
end
|
||||
end
|
||||
|
||||
defp current_user_can_access?(_conn, %Plausible.Site{public: true}) do
|
||||
true
|
||||
end
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ defmodule PlausibleWeb.Router do
|
|||
get "/:domain/operating-systems", StatsController, :operating_systems
|
||||
get "/:domain/browsers", StatsController, :browsers
|
||||
get "/:domain/compare", StatsController, :compare
|
||||
get "/:domain/current-visitors", StatsController, :current_visitors
|
||||
end
|
||||
|
||||
scope "/", PlausibleWeb do
|
||||
|
|
|
|||
|
|
@ -1,7 +1,15 @@
|
|||
<div class="pt-12"></div>
|
||||
<div class="container pb-32" data-site-domain="<%= @site.domain %>">
|
||||
<div class="w-full sm:flex justify-between items-center">
|
||||
<h2 class="text-center sm:text-left sm:mr-8">Analytics for <%= link(@site.domain, to: "//" <> @site.domain, target: "_blank") %></h2>
|
||||
<div class="w-full sm:flex items-center">
|
||||
<h2 class="text-center sm:text-left sm:mr-8">Analytics for <%= link(@site.domain, to: "//" <> @site.domain, target: "_blank") %></h2>
|
||||
<div class="text-sm font-bold text-grey-darker">
|
||||
<svg class="w-2 mr-1 fill-current text-green" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle cx="8" cy="8" r="8"/>
|
||||
</svg>
|
||||
<span id="current-visitors"><%= @current_visitors %></span> current visitors
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-4 sm:mt-0">
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/flatpickr/dist/flatpickr.min.css">
|
||||
<script src="https://cdn.jsdelivr.net/npm/flatpickr"></script>
|
||||
|
|
|
|||
|
|
@ -143,6 +143,48 @@ defmodule Plausible.StatsTest do
|
|||
end
|
||||
end
|
||||
|
||||
describe "current_visitors" do
|
||||
test "counts user ids seen in the last 5 minutes" do
|
||||
site = insert(:site)
|
||||
|
||||
insert(:pageview, %{
|
||||
hostname: site.domain,
|
||||
user_id: UUID.uuid4(),
|
||||
})
|
||||
|
||||
insert(:pageview, %{
|
||||
hostname: site.domain,
|
||||
user_id: UUID.uuid4(),
|
||||
inserted_at: Timex.now() |> Timex.shift(minutes: -4)
|
||||
})
|
||||
|
||||
insert(:pageview, %{
|
||||
hostname: site.domain,
|
||||
user_id: UUID.uuid4(),
|
||||
inserted_at: Timex.now() |> Timex.shift(minutes: -6)
|
||||
})
|
||||
|
||||
assert Stats.current_visitors(site) == 2
|
||||
end
|
||||
|
||||
test "counts unique user ids" do
|
||||
site = insert(:site)
|
||||
id = UUID.uuid4()
|
||||
|
||||
insert(:pageview, %{
|
||||
hostname: site.domain,
|
||||
user_id: id,
|
||||
})
|
||||
|
||||
insert(:pageview, %{
|
||||
hostname: site.domain,
|
||||
user_id: id,
|
||||
})
|
||||
|
||||
assert Stats.current_visitors(site) == 1
|
||||
end
|
||||
end
|
||||
|
||||
defp months_ago(months) do
|
||||
Timex.now() |> Timex.shift(months: -months)
|
||||
end
|
||||
|
|
|
|||
Loading…
Reference in New Issue