-include_lib("stdlib/include/qlc.hrl").
-import(lists, [reverse/1, any/2, map/2, sublist/3, filter/2]).
--import(euphorik_minichat, [resultat_transaction/1]).
+-import(euphorik_bd, [resultat_transaction/1]).
-import(qlc, [e/1, q/1, keysort/3]).
-import(mnesia, [table/1, transaction/1]).
% Message est le message de type #minichat et Parents une liste d'Id.
% Plus est un bool. Si Plus vaut true alors il y a encore des messages.
% Si il n'y a pas de nouveaux message alors la fonction est bloquante et attend un nouveau message.
-% @spec conversations([{integer(), integer()}], integer(), integer(), integer()) -> [Conversation()]
+% @spec conversations([{integer(), integer(), integer()}], integer(), integer(), integer()) -> [Conversation()]
conversations(Racines, N, D, P) ->
% écoute des nouveaux messages
case subscribe(minichat, 2) of
% Ajoute les parents de chaque message.
% @spec mise_en_forme_conversation([integer()]) -> [{integer(), [integer()]}]
mise_en_forme_conversation(Messages) ->
- lists:foldl(
+ lists:foldr(
fun(Id, Acc) ->
- case euphorik_minichat:message_by_id(Id) of
+ case euphorik_bd:message_by_id(Id) of
{ok, Message} ->
[{Message, parents(Id)} | Acc];
_ ->
% Racines est une liste de tuple {Id, P} des racines des conversations ou P est la page et Id l'id du message.
% @spec conversations_detailees([{integer(), integer()}], integer(), integer(), integer()) -> [[integer()] | Conversation_detailee()]
conversations_detailees(Racines, N, D, P) ->
- Conversations = map(fun({Racine, P_conv}) -> conversation(Racine, N, D, P_conv) end, Racines),
+ Conversations = map(fun({Racine, P_conv, Dernier}) -> conversation(Racine, N, Dernier, P_conv) end, Racines),
Conversation_principale = resultat_transaction(transaction(fun() ->
Curseur = qlc:cursor(q([E#minichat.id || E <- qlc:sort(table(minichat), [{order, descending}])])),
{CP, Plus} = conversation_principale(Curseur, Conversations, N, P),
qlc:delete_cursor(Curseur),
- {reverse([M || M <- CP, M > D]), Plus} % filtre en fonction de D
+ {[M || M <- CP, M > D], Plus} % filtre en fonction de D
end)),
[Conversation_principale | Conversations].
% et la liste de conversations.
% N est le nombre de messages que l'on souhaite.
% P est le numéro de la page (1, 2, 3...)
-% Renvoie {[Id], Plus}
-% @spec conversation_principale(qlc:QueryCursor(), [Conversation_detailee()], integer(), integer())
+% @spec conversation_principale(qlc:QueryCursor(), [Conversation_detailee()], integer(), integer()) -> {[Id], Plus}
conversation_principale(C, Conversations, N, P) ->
- CP = conversation_principale2(C, lists:flatten(map(fun({C2, _, X, _}) -> C2 -- X end, Conversations)), N + 1, (P - 1) * N),
+ % on prend en message de plus pour savoir s'il y en a plus que ce que l'on désire
+ CP = reverse(conversation_principale2(C, lists:flatten(map(fun({C2, _, X, _}) -> C2 -- X end, Conversations)), N + 1, (P - 1) * N)),
Plus = length(CP) =:= N + 1,
{
if Plus ->
% @spec conversation([integer()], integer(), integer(), integer()) -> Conversation_detailee()
conversation(R, N, D, P) ->
{C, X} = conversation([], [R], []),
- Decalage = N*(P-1)+1,
+ Decalage = N * (P - 1) + 1,
{
reverse(C),
if Decalage > length(C) ->
[];
true ->
- reverse(filter(
+ filter(
fun(E) -> E > D end,
- sublist(C, Decalage, N)
- ))
+ reverse(sublist(C, Decalage, N))
+ )
end,
reverse(X),
Decalage + N - 1 < length(C)
conversation(Messages, [M | Reste], X) ->
Est_deja_traite = any(fun(E) -> E =:= M end, Messages),
if Est_deja_traite ->
- conversation(Messages, Reste, X);
- true ->
- Enfants = enfants(M),
- Parents = parents(M),
- % un message est dit exiterne si un de ses parent ne fait pas partie de la conversation ou si un de ses parents fait partie de X
- Est_message_externe = Parents -- Messages =/= [] orelse intersection(Parents, X) =/= [],
- conversation([M | Messages], Reste ++ Enfants, if Est_message_externe -> [M | X]; true -> X end)
+ conversation(Messages, Reste, X);
+ true ->
+ Enfants = enfants(M),
+ Parents = parents(M),
+ % un message est dit externe si un de ses parent ne fait pas partie de la conversation ou si un de ses parents fait partie de X
+ Est_message_externe = Parents -- Messages =/= [] orelse intersection(Parents, X) =/= [],
+ conversation([M | Messages], lists:merge(Reste, Enfants), if Est_message_externe -> [M | X]; true -> X end)
end;
conversation(Messages, [], X) ->
{Messages, X}.