diff --git a/apps/roster/src/protocol/roster_room.erl b/apps/roster/src/protocol/roster_room.erl index 7edaf58058fbb582f32c2c51cf81cfc72ba58d32..c177d1890d44cc4243635d4676de6e4d3d0f6933 100644 --- a/apps/roster/src/protocol/roster_room.erl +++ b/apps/roster/src/protocol/roster_room.erl @@ -400,10 +400,9 @@ info(#'Room'{status = Mute, id = Room}, Req, #cx{params = ClientId, client_pid = #'Member'{phone_id = PhoneId} -> [Phone, RosterId] = roster:parts_phone_id(PhoneId), case kvs:get('Roster', RosterId) of - {ok, #'Roster'{roomlist = Rooms} = Roster} -> + {ok, #'Roster'{roomlist = Rooms}} -> #'Room'{} = R = lists:keyfind(Room, #'Room'.id, Rooms), - Roomlist = lists:ukeymerge(#'Room'.id, [R#'Room'{status = Mute2}], Rooms), - kvs:put(Roster#'Roster'{roomlist = Roomlist}), + roster:update_rooms(RosterId, R#'Room'{status = Mute2}), roster:send_ses(C, Phone, R#'Room'{status = Mute}), <<>>; #error{} -> diff --git a/apps/roster/src/roster.erl b/apps/roster/src/roster.erl index b40dafc87da70cfe9a715ee919936a6bdeb0f454..e50cc9331be1b4cc21b8ba6dab5557e678515805 100644 --- a/apps/roster/src/roster.erl +++ b/apps/roster/src/roster.erl @@ -1479,45 +1479,31 @@ roomlist(Id, N) -> case kvs:get('Roster', Id) of {ok, R} -> roomlist(R, N); _ -> room(Roster, Room) -> room(Roster, Room, [], 0). room(#'Roster'{} = Roster, #'Room'{id = Name} = Room, [], LastSync) -> room(Roster, Room, kvs_stream:load_writer(#muc{name = Name}), LastSync); -room(#'Roster'{id = Id, phone = Phone}, #'Room'{id = Name, last_msg = LMId} = Room, - #writer{} = W, _LastSync) -> +room(#'Roster'{id = Id, phone = Phone}, #'Room'{id = Name, status = St0} = Room, #writer{} = W, _LastSync) -> Local = phone_id(Phone, Id), - case muc_member(Local, Name) of - #'Member'{id = UID, reader = Reader} = Member when Reader > 0 -> - Rec = case is_integer(LMId) of true -> {'Message', LMId};_ -> W end, -%% TODO replace with code below after rewriting unread_msg -%% TODO now update status may be calculated without while and status_msg -%% Rec = case is_integer(LMId) of true -> {'Message', LMId}; -%% _ -> {ok, #'Room'{last_msg = LMId2}} = kvs:get('Room', Name), -%% {'Message', LMId2} end, + case muc_member(Local, Name, presence) of + #'Member'{reader = Reader, status = St} = Member when Reader > 0 -> {Unread, LastMsg, Mentions} = - case unread_msg(Rec, Reader, Member) of + case unread_msg(W, Reader, Member) of {_, #'Message'{}, _} = Res -> Res; _Res -> {0,[],[]} end, -%% {Unread, LastMsg = #'Message'{from = PMention, mentioned = Mentioned}, Mentions} -%% = unread_msg(Rec, Reader, UID), %%TODO fix if writer is empty - {ok, #'Room'{readers = Readers}} = kvs:get('Room', Name), LastPhoneId = case LastMsg of #'Message'{from = LPhoneId} -> LPhoneId; _ -> 0 end, - Membrs = lists:flatten( - case muc_member(LastPhoneId, Name, presence) of - #'Member'{phone_id = Local} = M -> [M]; - M -> [M2 || M2 <- [muc_member(Local, Name, presence), M]] - end), - MentionMembers = case LastMsg of - #'Message'{from = PMention, mentioned = Mentioned} -> lists:flatten(case lists:member(UID, Mentioned) of - true -> [muc_member(PMention, Name)]; _ -> [] end); - [] -> [] end, - Members = Membrs ++ case MentionMembers of - [#'Member'{id = MentionId}] -> - case lists:keymember(MentionId, #'Member'.id, Membrs) of - false -> MentionMembers; _ -> [] end; _ -> [] end, + Members = case LastPhoneId == Local of + true -> [Member]; + false -> [Member, muc_member(LastPhoneId, Name, presence)] + end, {Admins, Members2} = roster:split_members(Members), + Status = case St of + removed -> removed; + _ -> St0 + end, roster:reader_cache( Room#'Room'{unread = Unread, last_msg = LastMsg, links = [roster_link:get_link(Name)], - mentions = Mentions, admins = Admins, members = Members2, readers = Readers}); + status = Status, mentions = Mentions, admins = Admins, + members = Members2, readers = Readers}); _ -> [] end; room(#'Roster'{id = RosterId, roomlist = Rooms} = R, RoomId, W, LastSync) -> case lists:keyfind(RoomId, #'Room'.id, Rooms) of diff --git a/eqc/server_eqc.erl b/eqc/server_eqc.erl index 51781068d0ec06d5bd314b582a85f765db0f1033..2780f3c2de8f636a3ac96fb9cc7a70e85b7aa5eb 100644 --- a/eqc/server_eqc.erl +++ b/eqc/server_eqc.erl @@ -69,6 +69,7 @@ -record(room_info, { name :: string() + , status :: [] | atom() , members :: list(#member{}) , admins :: list(#member{}) , readers :: list(msg_id()) @@ -459,10 +460,23 @@ check_friend(S, Phone, #contact{ id = FriendId, reader = [_, Reader], unread = Unread }) -> check_feed(S, Phone, p2p_feed(Phone, phone_id_phone(S, FriendId)), Reader, Unread). -check_room(S, Phone, #room_info{ name = Room0, unread = Unread, admins = As, members = Ms }) -> +check_room(S, Phone, #room_info{ name = Room0, unread = Unread, admins = As, members = Ms, status = St }) -> Room = get_room_id_by_name(S, Room0), #member{ reader = Reader } = lists:keyfind(user_phone_id(S, Phone), #member.phone_id, As ++ Ms), - check_feed(S, Phone, {muc, Room}, Reader, Unread). + conj([check_feed(S, Phone, {muc, Room}, Reader, Unread), + check_status(S, Phone, Room, St)]). + +check_status(S, Phone, Room, Status) -> + #room{ members = Ms, admins = As } = get_room(S, Room), + case Status of + admin -> tag(status, lists:member(Phone, As)); + member -> tag(status, lists:member(Phone, Ms)); + [] -> tag(status, lists:member(Phone, As ++ Ms)); + mute -> tag(status, lists:member(Phone, As ++ Ms)); + delete -> tag(status, lists:member(Phone, As ++ Ms)); + _ -> tag(status, {false, Status}) + end. +%% check_status(_S, _Phone, _Room, _X) -> true. check_feed(S, Phone, FeedId, LastRead, Unread) -> ExpLastRead = feed_last_seen(S, Phone, FeedId), @@ -1542,10 +1556,11 @@ to_message(#'Message'{id = Id, files = Files, from = From0, type = Type}) -> end, #message{ id = Id, payload = Msg, from = From }. -to_room(#'Room'{ name = Name0, readers = Readers, unread = Unread, members = Members, admins = Admins }) -> +to_room(#'Room'{ name = Name0, readers = Readers, unread = Unread, members = Members, admins = Admins, status = Status }) -> [Name | _] = binary:split(Name0, <<"-">>), - #room_info{ name = Name, members = [to_member(M) || M <- Members], - admins = [to_member(A) || A <- Admins], unread = Unread, readers = Readers }. + #room_info{ name = Name, status = Status, + members = [to_member(M) || M <- Members], admins = [to_member(A) || A <- Admins], + unread = Unread, readers = Readers }. to_contact(#'Contact'{ phone_id = Id, reader = Reader, unread = Unread, status = Status }) -> #contact{ id = Id, reader = Reader, unread = Unread, status = Status }. diff --git a/test/nynja.erl b/test/nynja.erl index e49817458c97ada74c49a7c5823bf34ccbd9d61a..764bd11c7520dc03cef99d6ea0947ffde829a487 100644 --- a/test/nynja.erl +++ b/test/nynja.erl @@ -65,6 +65,7 @@ register_profile(Sys, Info, Connect) -> Profile = #'Profile'{ phone = PhoneLink, rosters = [Roster], update = now_msec(), settings = Settings, status = create }, + timer:sleep(25), %% avoid race between subscriptions and get_profile #mqtt_packet{ payload = #'Profile'{rosters = [#'Roster'{}]} } = do_register_profile(Sys, Profile), case Connect of true -> connect_user(Phone, PhoneLink, RosterUUID); @@ -94,7 +95,7 @@ connect_user_(Phone, PhoneLink, RosterUUID) -> connect_user(Phone, PhoneLink, RosterUUID) -> User = connect_user_(Phone, PhoneLink, RosterUUID), - %% timer:sleep(25), %% avoid race between subscriptions and get_profile + timer:sleep(25), %% avoid race between subscriptions and get_profile #mqtt_packet{ payload = #'Profile'{ rosters = [#'Roster'{ id = RosterIx }] } } = get_profile(User, 10000),