1 |
|
%%%------------------------------------------------------------------- |
2 |
|
%%% @copyright (C) 2021, Erlang-Solutions |
3 |
|
%%% @doc |
4 |
|
%%% This module implements [XEP-0333: Chat Markers] helper functions |
5 |
|
%%% @end |
6 |
|
%%%------------------------------------------------------------------- |
7 |
|
-module(mongoose_chat_markers). |
8 |
|
|
9 |
|
-include("mongoose_ns.hrl"). |
10 |
|
-include_lib("exml/include/exml.hrl"). |
11 |
|
|
12 |
|
%% Markers |
13 |
|
-export([has_chat_markers/1, |
14 |
|
list_chat_markers/1, |
15 |
|
chat_marker_names/0]). |
16 |
|
|
17 |
|
-type id() :: binary(). |
18 |
|
-type chat_marker_type() :: received | displayed | acknowledged. |
19 |
|
-type chat_marker_element() :: {chat_marker_type(), id()}. |
20 |
|
-export_type([chat_marker_type/0]). |
21 |
|
-export_type([chat_marker_element/0]). |
22 |
|
|
23 |
|
%% API |
24 |
|
|
25 |
|
-spec has_chat_markers(exml:element()) -> boolean(). |
26 |
|
has_chat_markers(Packet) -> |
27 |
3977 |
[] =/= list_chat_markers(Packet). |
28 |
|
|
29 |
|
-spec list_chat_markers(exml:element()) -> [chat_marker_element()]. |
30 |
|
list_chat_markers(#xmlel{children = Children}) -> |
31 |
4065 |
lists:filtermap(fun is_chat_marker_element/1, Children). |
32 |
|
|
33 |
|
-spec chat_marker_names() -> [binary()]. |
34 |
|
chat_marker_names() -> |
35 |
84 |
[<<"received">>, <<"displayed">>, <<"acknowledged">>]. |
36 |
|
|
37 |
|
%% Internal functions |
38 |
|
|
39 |
|
-spec is_chat_marker_element(exml:element()) -> |
40 |
|
false | {true, {chat_marker_type(), Id :: binary}}. |
41 |
|
is_chat_marker_element(#xmlel{name = <<"received">>} = El) -> |
42 |
100 |
check_chat_marker_attributes(received, El); |
43 |
|
is_chat_marker_element(#xmlel{name = <<"displayed">>} = El) -> |
44 |
1407 |
check_chat_marker_attributes(displayed, El); |
45 |
|
is_chat_marker_element(#xmlel{name = <<"acknowledged">>} = El) -> |
46 |
56 |
check_chat_marker_attributes(acknowledged, El); |
47 |
|
is_chat_marker_element(_) -> |
48 |
3585 |
false. |
49 |
|
|
50 |
|
-spec check_chat_marker_attributes(chat_marker_type(), exml:element()) -> |
51 |
|
false | {true, chat_marker_element()}. |
52 |
|
check_chat_marker_attributes(Type, El) -> |
53 |
1563 |
NS = exml_query:attr(El, <<"xmlns">>), |
54 |
1563 |
Id = exml_query:attr(El, <<"id">>), |
55 |
1563 |
?NS_CHAT_MARKERS =:= NS andalso Id =/= undefined andalso {true, {Type, Id}}. |