add: last_online and online indicators
This commit is contained in:
parent
d3d0c41334
commit
e0a6072cc4
12 changed files with 177 additions and 9 deletions
|
@ -24,6 +24,7 @@
|
|||
--color-shadow: rgba(0, 0, 0, 0.08);
|
||||
--color-red: hsl(0, 84%, 40%);
|
||||
--color-green: hsl(100, 84%, 20%);
|
||||
--color-yellow: hsl(41, 63%, 75%);
|
||||
--radius: 6px;
|
||||
--circle: 360px;
|
||||
--shadow-x-offset: 0;
|
||||
|
@ -54,6 +55,7 @@
|
|||
--color-link: #93c5fd;
|
||||
--color-red: hsl(0, 94%, 82%);
|
||||
--color-green: hsl(100, 94%, 82%);
|
||||
--color-yellow: hsl(41, 63%, 65%);
|
||||
}
|
||||
|
||||
* {
|
||||
|
|
|
@ -111,9 +111,13 @@ show_community=true) -%} {% if community and show_community %}
|
|||
|
||||
<div class="flex flex-col w-full gap-1">
|
||||
<div class="flex flex-wrap gap-2 items-center">
|
||||
<a href="/@{{ owner.username }}"
|
||||
>{{ components::username(user=owner) }}</a
|
||||
>
|
||||
<div class="flex">
|
||||
<a href="/@{{ owner.username }}"
|
||||
>{{ components::username(user=owner) }}</a
|
||||
>
|
||||
|
||||
{{ components::online_indicator(user=owner) }}
|
||||
</div>
|
||||
|
||||
<span class="fade date">{{ post.created }}</span>
|
||||
|
||||
|
@ -274,4 +278,45 @@ show_community=true) -%} {% if community and show_community %}
|
|||
</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
{%- endmacro %}
|
||||
{%- endmacro %} {% macro online_indicator(user) -%} {% if not
|
||||
user.settings.private_last_online or is_helper %}
|
||||
<div
|
||||
class="online_indicator"
|
||||
style="display: contents"
|
||||
hook="online_indicator"
|
||||
hook-arg:last_seen="{{ user.last_seen }}"
|
||||
>
|
||||
<div style="display: none" hook_ui_ident="online" title="Online">
|
||||
<svg
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
style="fill: var(--color-green)"
|
||||
>
|
||||
<circle cx="12" cy="12" r="6"></circle>
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<div style="display: none" hook_ui_ident="idle" title="Idle">
|
||||
<svg
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
style="fill: var(--color-yellow)"
|
||||
>
|
||||
<circle cx="12" cy="12" r="6"></circle>
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<div style="display: none" hook_ui_ident="offline" title="Offline">
|
||||
<svg
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
style="fill: hsl(0, 0%, 50%)"
|
||||
>
|
||||
<circle cx="12" cy="12" r="6"></circle>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %} {%- endmacro %}
|
||||
|
|
|
@ -72,6 +72,14 @@
|
|||
<span class="notification chip">Joined</span>
|
||||
<span class="date">{{ profile.created }}</span>
|
||||
</div>
|
||||
|
||||
{% if not profile.settings.private_last_seen or is_self
|
||||
or is_helper %}
|
||||
<div class="w-full flex justify-between items-center">
|
||||
<span class="notification chip">Last seen</span>
|
||||
<span class="date">{{ profile.last_seen }}</span>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -493,6 +493,11 @@
|
|||
"{{ profile.settings.private_communities }}",
|
||||
"checkbox",
|
||||
],
|
||||
[
|
||||
["private_last_seen", "Keep my last seen time private"],
|
||||
"{{ profile.settings.private_last_seen }}",
|
||||
"checkbox",
|
||||
],
|
||||
],
|
||||
settings,
|
||||
);
|
||||
|
|
|
@ -103,6 +103,7 @@
|
|||
atto["hooks::character_counter.init"]();
|
||||
atto["hooks::long_text.init"]();
|
||||
atto["hooks::alt"]();
|
||||
atto["hooks::online_indicator"]();
|
||||
// atto["hooks::ips"]();
|
||||
atto["hooks::check_reactions"]();
|
||||
atto["hooks::tabs"]();
|
||||
|
@ -110,6 +111,14 @@
|
|||
});
|
||||
</script>
|
||||
|
||||
{% if user %}
|
||||
<script data-turbo-permanent="true" id="update-seen-script">
|
||||
document.documentElement.addEventListener("turbo:load", () => {
|
||||
trigger("me::seen");
|
||||
});
|
||||
</script>
|
||||
{% endif %}
|
||||
|
||||
<!-- dialogs -->
|
||||
<dialog id="link_filter">
|
||||
<div class="inner">
|
||||
|
|
|
@ -371,6 +371,43 @@ media_theme_pref();
|
|||
}
|
||||
});
|
||||
|
||||
self.define("last_seen_just_now", (_, last_seen) => {
|
||||
const now = new Date().getTime();
|
||||
const maximum_time_to_be_considered_online = 60000 * 2; // 2 minutes
|
||||
return now - last_seen <= maximum_time_to_be_considered_online;
|
||||
});
|
||||
|
||||
self.define("last_seen_recently", (_, last_seen) => {
|
||||
const now = new Date().getTime();
|
||||
const maximum_time_to_be_considered_idle = 60000 * 5; // 5 minutes
|
||||
return now - last_seen <= maximum_time_to_be_considered_idle;
|
||||
});
|
||||
|
||||
self.define("hooks::online_indicator", ({ $ }) => {
|
||||
for (const element of Array.from(
|
||||
document.querySelectorAll("[hook=online_indicator]") || [],
|
||||
)) {
|
||||
const last_seen = Number.parseInt(
|
||||
element.getAttribute("hook-arg:last_seen"),
|
||||
);
|
||||
|
||||
const is_online = $.last_seen_just_now(last_seen);
|
||||
const is_idle = $.last_seen_recently(last_seen);
|
||||
|
||||
const offline = element.querySelector("[hook_ui_ident=offline]");
|
||||
const online = element.querySelector("[hook_ui_ident=online]");
|
||||
const idle = element.querySelector("[hook_ui_ident=idle]");
|
||||
|
||||
if (is_online) {
|
||||
online.style.display = "contents";
|
||||
} else if (is_idle) {
|
||||
idle.style.display = "contents";
|
||||
} else {
|
||||
offline.style.display = "contents";
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
self.define(
|
||||
"hooks::attach_to_partial",
|
||||
({ $ }, partial, full, attach, wrapper, page, run_on_load) => {
|
||||
|
|
|
@ -150,4 +150,16 @@
|
|||
`/mod_panel/file_report?asset=${asset}&asset_type=${asset_type}`,
|
||||
);
|
||||
});
|
||||
|
||||
self.define("seen", () => {
|
||||
fetch("/api/v1/auth/profile/me/seen", {
|
||||
method: "POST",
|
||||
})
|
||||
.then((res) => res.json())
|
||||
.then((res) => {
|
||||
if (!res.ok) {
|
||||
trigger("atto::toast", ["error", res.message]);
|
||||
}
|
||||
});
|
||||
});
|
||||
})();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue