diff options
Diffstat (limited to '')
-rw-r--r-- | linden/indra/newview/llimview.cpp | 503 |
1 files changed, 344 insertions, 159 deletions
diff --git a/linden/indra/newview/llimview.cpp b/linden/indra/newview/llimview.cpp index 468c75e..2f9c1eb 100644 --- a/linden/indra/newview/llimview.cpp +++ b/linden/indra/newview/llimview.cpp | |||
@@ -12,12 +12,12 @@ | |||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | 12 | * ("GPL"), unless you have obtained a separate licensing agreement |
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 13 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
15 | * online at http://secondlife.com/developers/opensource/gplv2 | 15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
16 | * | 16 | * |
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlife.com/developers/opensource/flossexception | 20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
21 | * | 21 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 22 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 23 | * that you have read and understood your obligations described above, |
@@ -46,7 +46,6 @@ | |||
46 | #include "llagent.h" | 46 | #include "llagent.h" |
47 | #include "llcallingcard.h" | 47 | #include "llcallingcard.h" |
48 | #include "llchat.h" | 48 | #include "llchat.h" |
49 | #include "llviewerwindow.h" | ||
50 | #include "llresmgr.h" | 49 | #include "llresmgr.h" |
51 | #include "llfloaterchat.h" | 50 | #include "llfloaterchat.h" |
52 | #include "llfloaterchatterbox.h" | 51 | #include "llfloaterchatterbox.h" |
@@ -65,6 +64,7 @@ | |||
65 | #include "llcallingcard.h" | 64 | #include "llcallingcard.h" |
66 | #include "lltoolbar.h" | 65 | #include "lltoolbar.h" |
67 | #include "llviewermessage.h" | 66 | #include "llviewermessage.h" |
67 | #include "llviewerwindow.h" | ||
68 | #include "llnotify.h" | 68 | #include "llnotify.h" |
69 | #include "llviewerregion.h" | 69 | #include "llviewerregion.h" |
70 | 70 | ||
@@ -84,11 +84,12 @@ LLIMMgr* gIMMgr = NULL; | |||
84 | //*FIXME: make these all either UIStrings or Strings | 84 | //*FIXME: make these all either UIStrings or Strings |
85 | static LLString sOnlyUserMessage; | 85 | static LLString sOnlyUserMessage; |
86 | static LLUIString sOfflineMessage; | 86 | static LLUIString sOfflineMessage; |
87 | |||
88 | static std::map<std::string,LLString> sEventStringsMap; | ||
89 | static std::map<std::string,LLString> sErrorStringsMap; | ||
90 | static std::map<std::string,LLString> sForceCloseSessionMap; | ||
91 | static LLUIString sInviteMessage; | 87 | static LLUIString sInviteMessage; |
88 | |||
89 | std::map<std::string,LLString> LLFloaterIM::sEventStringsMap; | ||
90 | std::map<std::string,LLString> LLFloaterIM::sErrorStringsMap; | ||
91 | std::map<std::string,LLString> LLFloaterIM::sForceCloseSessionMap; | ||
92 | |||
92 | // | 93 | // |
93 | // Helper Functions | 94 | // Helper Functions |
94 | // | 95 | // |
@@ -160,22 +161,82 @@ BOOL LLFloaterIM::postBuild() | |||
160 | sOnlyUserMessage = getFormattedUIString("only_user_message"); | 161 | sOnlyUserMessage = getFormattedUIString("only_user_message"); |
161 | sOfflineMessage = getUIString("offline_message"); | 162 | sOfflineMessage = getUIString("offline_message"); |
162 | 163 | ||
163 | sErrorStringsMap["generic"] = | 164 | sInviteMessage = getUIString("invite_message"); |
164 | getFormattedUIString("generic_request_error"); | 165 | |
165 | sErrorStringsMap["unverified"] = | 166 | if ( sErrorStringsMap.find("generic") == sErrorStringsMap.end() ) |
166 | getFormattedUIString("insufficient_perms_error"); | 167 | { |
167 | sErrorStringsMap["no_user_911"] = | 168 | sErrorStringsMap["generic"] = |
168 | getFormattedUIString("user_no_help"); | 169 | getFormattedUIString("generic_request_error"); |
170 | } | ||
171 | |||
172 | if ( sErrorStringsMap.find("unverified") == | ||
173 | sErrorStringsMap.end() ) | ||
174 | { | ||
175 | sErrorStringsMap["unverified"] = | ||
176 | getFormattedUIString("insufficient_perms_error"); | ||
177 | } | ||
178 | |||
179 | if ( sErrorStringsMap.end() == | ||
180 | sErrorStringsMap.find("no_ability") ) | ||
181 | { | ||
182 | sErrorStringsMap["no_ability"] = | ||
183 | getFormattedUIString("no_ability_error"); | ||
184 | } | ||
169 | 185 | ||
170 | sEventStringsMap["add"] = | 186 | if ( sErrorStringsMap.end() == |
171 | getFormattedUIString("add_session_event"); | 187 | sErrorStringsMap.find("muted") ) |
172 | sEventStringsMap["message"] = | 188 | { |
173 | getFormattedUIString("message_session_event"); | 189 | sErrorStringsMap["muted"] = |
190 | getFormattedUIString("muted_error"); | ||
191 | } | ||
174 | 192 | ||
175 | sForceCloseSessionMap["removed"] = | 193 | if ( sErrorStringsMap.end() == |
176 | getFormattedUIString("removed_from_group"); | 194 | sErrorStringsMap.find("not_a_moderator") ) |
195 | { | ||
196 | sErrorStringsMap["not_a_moderator"] = | ||
197 | getFormattedUIString("not_a_mod_error"); | ||
198 | } | ||
199 | |||
200 | if ( sErrorStringsMap.end() == | ||
201 | sErrorStringsMap.find("does not exist") ) | ||
202 | { | ||
203 | sErrorStringsMap["does not exist"] = | ||
204 | getFormattedUIString("session_does_not_exist_error"); | ||
205 | } | ||
206 | |||
207 | if ( sEventStringsMap.end() == sEventStringsMap.find("add") ) | ||
208 | { | ||
209 | sEventStringsMap["add"] = | ||
210 | getFormattedUIString("add_session_event"); | ||
211 | } | ||
212 | |||
213 | if ( sEventStringsMap.end() == sEventStringsMap.find("message") ) | ||
214 | { | ||
215 | sEventStringsMap["message"] = | ||
216 | getFormattedUIString("message_session_event"); | ||
217 | } | ||
218 | |||
219 | |||
220 | if ( sEventStringsMap.end() == sEventStringsMap.find("mute") ) | ||
221 | { | ||
222 | sEventStringsMap["mute"] = getFormattedUIString( | ||
223 | "mute_agent_event"); | ||
224 | } | ||
225 | |||
226 | if ( sForceCloseSessionMap.end() == | ||
227 | sForceCloseSessionMap.find("removed") ) | ||
228 | { | ||
229 | sForceCloseSessionMap["removed"] = | ||
230 | getFormattedUIString("removed_from_group"); | ||
231 | } | ||
232 | |||
233 | if ( sForceCloseSessionMap.end() == | ||
234 | sForceCloseSessionMap.find("no ability") ) | ||
235 | { | ||
236 | sForceCloseSessionMap["no ability"] = | ||
237 | getFormattedUIString("close_on_no_ability"); | ||
238 | } | ||
177 | 239 | ||
178 | sInviteMessage = getUIString("invite_message"); | ||
179 | return TRUE; | 240 | return TRUE; |
180 | } | 241 | } |
181 | 242 | ||
@@ -205,21 +266,31 @@ protected: | |||
205 | class LLIMMgr::LLIMSessionInvite | 266 | class LLIMMgr::LLIMSessionInvite |
206 | { | 267 | { |
207 | public: | 268 | public: |
208 | LLIMSessionInvite(const LLUUID& session_id, const LLString& session_name, const LLUUID& caller_id,const LLString& caller_name, EInstantMessage type, const LLString& session_handle, const LLString& notify_box) : | 269 | LLIMSessionInvite( |
209 | mSessionID(session_id), | 270 | const LLUUID& session_id, |
210 | mSessionName(session_name), | 271 | const LLString& session_name, |
211 | mCallerID(caller_id), | 272 | const LLUUID& caller_id, |
212 | mCallerName(caller_name), | 273 | const LLString& caller_name, |
213 | mType(type), | 274 | EInstantMessage type, |
214 | mSessionHandle(session_handle), | 275 | EInvitationType inv_type, |
215 | mNotifyBox(notify_box) | 276 | const LLString& session_handle, |
216 | {}; | 277 | const LLString& notify_box) : |
278 | mSessionID(session_id), | ||
279 | mSessionName(session_name), | ||
280 | mCallerID(caller_id), | ||
281 | mCallerName(caller_name), | ||
282 | mType(type), | ||
283 | mInvType(inv_type), | ||
284 | mSessionHandle(session_handle), | ||
285 | mNotifyBox(notify_box) | ||
286 | {}; | ||
217 | 287 | ||
218 | LLUUID mSessionID; | 288 | LLUUID mSessionID; |
219 | LLString mSessionName; | 289 | LLString mSessionName; |
220 | LLUUID mCallerID; | 290 | LLUUID mCallerID; |
221 | LLString mCallerName; | 291 | LLString mCallerName; |
222 | EInstantMessage mType; | 292 | EInstantMessage mType; |
293 | EInvitationType mInvType; | ||
223 | LLString mSessionHandle; | 294 | LLString mSessionHandle; |
224 | LLString mNotifyBox; | 295 | LLString mNotifyBox; |
225 | }; | 296 | }; |
@@ -309,7 +380,7 @@ LLIMMgr::LLIMMgr() : | |||
309 | LLFloaterIM* dummy_floater = new LLFloaterIM(); | 380 | LLFloaterIM* dummy_floater = new LLFloaterIM(); |
310 | delete dummy_floater; | 381 | delete dummy_floater; |
311 | 382 | ||
312 | mPendingVoiceInvitations = LLSD::emptyMap(); | 383 | mPendingInvitations = LLSD::emptyMap(); |
313 | mPendingAgentListUpdates = LLSD::emptyMap(); | 384 | mPendingAgentListUpdates = LLSD::emptyMap(); |
314 | } | 385 | } |
315 | 386 | ||
@@ -413,7 +484,6 @@ void LLIMMgr::addMessage( | |||
413 | if ( is_from_system ) // chat came from system | 484 | if ( is_from_system ) // chat came from system |
414 | { | 485 | { |
415 | floater->addHistoryLine( | 486 | floater->addHistoryLine( |
416 | other_participant_id, | ||
417 | msg, | 487 | msg, |
418 | gSavedSettings.getColor4("SystemChatColor")); | 488 | gSavedSettings.getColor4("SystemChatColor")); |
419 | } | 489 | } |
@@ -521,9 +591,10 @@ LLUUID LLIMMgr::addP2PSession(const std::string& name, | |||
521 | // the session, dialog specifies the type of session. If the session | 591 | // the session, dialog specifies the type of session. If the session |
522 | // exists, it is brought forward. Specifying id = NULL results in an | 592 | // exists, it is brought forward. Specifying id = NULL results in an |
523 | // im session to everyone. Returns the uuid of the session. | 593 | // im session to everyone. Returns the uuid of the session. |
524 | LLUUID LLIMMgr::addSession(const std::string& name, | 594 | LLUUID LLIMMgr::addSession( |
525 | EInstantMessage dialog, | 595 | const std::string& name, |
526 | const LLUUID& other_participant_id) | 596 | EInstantMessage dialog, |
597 | const LLUUID& other_participant_id) | ||
527 | { | 598 | { |
528 | LLUUID session_id = computeSessionID(dialog, other_participant_id); | 599 | LLUUID session_id = computeSessionID(dialog, other_participant_id); |
529 | 600 | ||
@@ -533,15 +604,16 @@ LLUUID LLIMMgr::addSession(const std::string& name, | |||
533 | LLDynamicArray<LLUUID> ids; | 604 | LLDynamicArray<LLUUID> ids; |
534 | ids.put(other_participant_id); | 605 | ids.put(other_participant_id); |
535 | 606 | ||
536 | floater = createFloater(session_id, | 607 | floater = createFloater( |
537 | other_participant_id, | 608 | session_id, |
538 | name, | 609 | other_participant_id, |
539 | ids, | 610 | name, |
540 | dialog, | 611 | ids, |
541 | TRUE); | 612 | dialog, |
613 | TRUE); | ||
542 | 614 | ||
543 | noteOfflineUsers(floater, ids); | 615 | noteOfflineUsers(floater, ids); |
544 | LLFloaterChatterBox::getInstance(LLSD())->showFloater(floater); | 616 | LLFloaterChatterBox::showInstance(session_id); |
545 | } | 617 | } |
546 | else | 618 | else |
547 | { | 619 | { |
@@ -554,36 +626,43 @@ LLUUID LLIMMgr::addSession(const std::string& name, | |||
554 | 626 | ||
555 | // Adds a session using the given session_id. If the session already exists | 627 | // Adds a session using the given session_id. If the session already exists |
556 | // the dialog type is assumed correct. Returns the uuid of the session. | 628 | // the dialog type is assumed correct. Returns the uuid of the session. |
557 | LLUUID LLIMMgr::addSession(const std::string& name, | 629 | LLUUID LLIMMgr::addSession( |
558 | EInstantMessage dialog, | 630 | const std::string& name, |
559 | const LLUUID& other_participant_id, | 631 | EInstantMessage dialog, |
560 | const LLDynamicArray<LLUUID>& ids) | 632 | const LLUUID& other_participant_id, |
633 | const LLDynamicArray<LLUUID>& ids) | ||
561 | { | 634 | { |
562 | if (0 == ids.getLength()) | 635 | if (0 == ids.getLength()) |
563 | { | 636 | { |
564 | return LLUUID::null; | 637 | return LLUUID::null; |
565 | } | 638 | } |
566 | 639 | ||
567 | LLUUID session_id = computeSessionID(dialog, | 640 | LLUUID session_id = computeSessionID( |
568 | other_participant_id); | 641 | dialog, |
642 | other_participant_id); | ||
569 | 643 | ||
570 | LLFloaterIMPanel* floater = findFloaterBySession(session_id); | 644 | LLFloaterIMPanel* floater = findFloaterBySession(session_id); |
571 | if(!floater) | 645 | if(!floater) |
572 | { | 646 | { |
573 | // On creation, use the first element of ids as the | 647 | // On creation, use the first element of ids as the |
574 | // "other_participant_id" | 648 | // "other_participant_id" |
575 | floater = createFloater(session_id, | 649 | floater = createFloater( |
576 | other_participant_id, | 650 | session_id, |
577 | name, | 651 | other_participant_id, |
578 | ids, | 652 | name, |
579 | dialog, | 653 | ids, |
580 | TRUE); | 654 | dialog, |
655 | TRUE); | ||
581 | 656 | ||
582 | if ( !floater ) return LLUUID::null; | 657 | if ( !floater ) return LLUUID::null; |
583 | 658 | ||
584 | noteOfflineUsers(floater, ids); | 659 | noteOfflineUsers(floater, ids); |
660 | LLFloaterChatterBox::showInstance(session_id); | ||
661 | } | ||
662 | else | ||
663 | { | ||
664 | floater->open(); | ||
585 | } | 665 | } |
586 | LLFloaterChatterBox::getInstance(LLSD())->showFloater(floater); | ||
587 | //mTabContainer->selectTabPanel(panel); | 666 | //mTabContainer->selectTabPanel(panel); |
588 | floater->setInputFocus(TRUE); | 667 | floater->setInputFocus(TRUE); |
589 | return floater->getSessionID(); | 668 | return floater->getSessionID(); |
@@ -599,6 +678,9 @@ void LLIMMgr::removeSession(const LLUUID& session_id) | |||
599 | mFloaters.erase(floater->getHandle()); | 678 | mFloaters.erase(floater->getHandle()); |
600 | LLFloaterChatterBox::getInstance(LLSD())->removeFloater(floater); | 679 | LLFloaterChatterBox::getInstance(LLSD())->removeFloater(floater); |
601 | //mTabContainer->removeTabPanel(floater); | 680 | //mTabContainer->removeTabPanel(floater); |
681 | |||
682 | clearPendingInviation(session_id); | ||
683 | clearPendingAgentListUpdates(session_id); | ||
602 | } | 684 | } |
603 | } | 685 | } |
604 | 686 | ||
@@ -608,9 +690,10 @@ void LLIMMgr::inviteToSession( | |||
608 | const LLUUID& caller_id, | 690 | const LLUUID& caller_id, |
609 | const LLString& caller_name, | 691 | const LLString& caller_name, |
610 | EInstantMessage type, | 692 | EInstantMessage type, |
693 | EInvitationType inv_type, | ||
611 | const LLString& session_handle) | 694 | const LLString& session_handle) |
612 | { | 695 | { |
613 | //ignore voice invites from voice-muted residents | 696 | //ignore invites from muted residents |
614 | if (gMuteListp->isMuted(caller_id)) | 697 | if (gMuteListp->isMuted(caller_id)) |
615 | { | 698 | { |
616 | return; | 699 | return; |
@@ -621,17 +704,26 @@ void LLIMMgr::inviteToSession( | |||
621 | BOOL ad_hoc_invite = FALSE; | 704 | BOOL ad_hoc_invite = FALSE; |
622 | if(type == IM_SESSION_P2P_INVITE) | 705 | if(type == IM_SESSION_P2P_INVITE) |
623 | { | 706 | { |
707 | //P2P is different...they only have voice invitations | ||
624 | notify_box_type = "VoiceInviteP2P"; | 708 | notify_box_type = "VoiceInviteP2P"; |
625 | } | 709 | } |
626 | else if (gAgent.isInGroup(session_id)) | 710 | else if ( gAgent.isInGroup(session_id) ) |
627 | { | 711 | { |
712 | //only really old school groups have voice invitations | ||
628 | notify_box_type = "VoiceInviteGroup"; | 713 | notify_box_type = "VoiceInviteGroup"; |
629 | } | 714 | } |
630 | else | 715 | else if ( inv_type == INVITATION_TYPE_VOICE ) |
631 | { | 716 | { |
717 | //else it's an ad-hoc | ||
718 | //and a voice ad-hoc | ||
632 | notify_box_type = "VoiceInviteAdHoc"; | 719 | notify_box_type = "VoiceInviteAdHoc"; |
633 | ad_hoc_invite = TRUE; | 720 | ad_hoc_invite = TRUE; |
634 | } | 721 | } |
722 | else if ( inv_type == INVITATION_TYPE_IMMEDIATE ) | ||
723 | { | ||
724 | notify_box_type = "InviteAdHoc"; | ||
725 | ad_hoc_invite = TRUE; | ||
726 | } | ||
635 | 727 | ||
636 | LLIMSessionInvite* invite = new LLIMSessionInvite( | 728 | LLIMSessionInvite* invite = new LLIMSessionInvite( |
637 | session_id, | 729 | session_id, |
@@ -639,6 +731,7 @@ void LLIMMgr::inviteToSession( | |||
639 | caller_id, | 731 | caller_id, |
640 | caller_name, | 732 | caller_name, |
641 | type, | 733 | type, |
734 | inv_type, | ||
642 | session_handle, | 735 | session_handle, |
643 | notify_box_type); | 736 | notify_box_type); |
644 | 737 | ||
@@ -666,7 +759,7 @@ void LLIMMgr::inviteToSession( | |||
666 | } | 759 | } |
667 | } | 760 | } |
668 | 761 | ||
669 | if ( !mPendingVoiceInvitations.has(session_id.asString()) ) | 762 | if ( !mPendingInvitations.has(session_id.asString()) ) |
670 | { | 763 | { |
671 | if (caller_name.empty()) | 764 | if (caller_name.empty()) |
672 | { | 765 | { |
@@ -684,7 +777,7 @@ void LLIMMgr::inviteToSession( | |||
684 | (void*)invite); | 777 | (void*)invite); |
685 | 778 | ||
686 | } | 779 | } |
687 | mPendingVoiceInvitations[session_id.asString()] = LLSD(); | 780 | mPendingInvitations[session_id.asString()] = LLSD(); |
688 | } | 781 | } |
689 | } | 782 | } |
690 | 783 | ||
@@ -699,10 +792,11 @@ void LLIMMgr::onInviteNameLookup(const LLUUID& id, const char* first, const char | |||
699 | LLString::format_map_t args; | 792 | LLString::format_map_t args; |
700 | args["[NAME]"] = invite->mCallerName; | 793 | args["[NAME]"] = invite->mCallerName; |
701 | 794 | ||
702 | LLNotifyBox::showXml(invite->mNotifyBox, | 795 | LLNotifyBox::showXml( |
703 | args, | 796 | invite->mNotifyBox, |
704 | inviteUserResponse, | 797 | args, |
705 | (void*)invite); | 798 | inviteUserResponse, |
799 | (void*)invite); | ||
706 | } | 800 | } |
707 | 801 | ||
708 | class LLViewerChatterBoxInvitationAcceptResponder : | 802 | class LLViewerChatterBoxInvitationAcceptResponder : |
@@ -711,10 +805,10 @@ class LLViewerChatterBoxInvitationAcceptResponder : | |||
711 | public: | 805 | public: |
712 | LLViewerChatterBoxInvitationAcceptResponder( | 806 | LLViewerChatterBoxInvitationAcceptResponder( |
713 | const LLUUID& session_id, | 807 | const LLUUID& session_id, |
714 | bool is_voice_invitation) | 808 | LLIMMgr::EInvitationType invitation_type) |
715 | { | 809 | { |
716 | mSessionID = session_id; | 810 | mSessionID = session_id; |
717 | mIsVoiceInvitiation = is_voice_invitation; | 811 | mInvitiationType = invitation_type; |
718 | } | 812 | } |
719 | 813 | ||
720 | void result(const LLSD& content) | 814 | void result(const LLSD& content) |
@@ -738,48 +832,66 @@ public: | |||
738 | //but unfortunately, our base that we are receiving here | 832 | //but unfortunately, our base that we are receiving here |
739 | //may not be the most up to date. It was accurate at | 833 | //may not be the most up to date. It was accurate at |
740 | //some point in time though. | 834 | //some point in time though. |
741 | floaterp->setSpeakersList(content["agents"]); | 835 | floaterp->setSpeakers(content); |
742 | 836 | ||
743 | //we now have our base of users in the session | 837 | //we now have our base of users in the session |
744 | //that was accurate at some point, but maybe not now | 838 | //that was accurate at some point, but maybe not now |
745 | //so now we apply all of the udpates we've received | 839 | //so now we apply all of the udpates we've received |
746 | //in case of race conditions | 840 | //in case of race conditions |
747 | |||
748 | //reapplying a user entrance will do nothing | ||
749 | //reapplying a user leaving will not have the user | ||
750 | //in our base. So it's all good | ||
751 | floaterp->updateSpeakersList( | 841 | floaterp->updateSpeakersList( |
752 | gIMMgr->getPendingAgentListUpdates(mSessionID)); | 842 | gIMMgr->getPendingAgentListUpdates(mSessionID)); |
753 | 843 | ||
754 | if ( mIsVoiceInvitiation ) | 844 | if ( mInvitiationType == LLIMMgr::INVITATION_TYPE_VOICE ) |
755 | { | 845 | { |
756 | floaterp->requestAutoConnect(); | 846 | floaterp->requestAutoConnect(); |
757 | LLFloaterIMPanel::onClickStartCall(floaterp); | 847 | LLFloaterIMPanel::onClickStartCall(floaterp); |
758 | // always open IM window when connecting to voice | 848 | // always open IM window when connecting to voice |
759 | LLFloaterChatterBox::showInstance(TRUE); | 849 | LLFloaterChatterBox::showInstance(TRUE); |
760 | } | 850 | } |
851 | else if ( mInvitiationType == LLIMMgr::INVITATION_TYPE_IMMEDIATE ) | ||
852 | { | ||
853 | LLFloaterChatterBox::showInstance(TRUE); | ||
854 | } | ||
761 | } | 855 | } |
762 | 856 | ||
763 | gIMMgr->clearPendingAgentListUpdates(mSessionID); | 857 | gIMMgr->clearPendingAgentListUpdates(mSessionID); |
764 | if ( mIsVoiceInvitiation ) | 858 | gIMMgr->clearPendingInviation(mSessionID); |
765 | { | ||
766 | gIMMgr->clearPendingVoiceInviation(mSessionID); | ||
767 | } | ||
768 | } | 859 | } |
769 | } | 860 | } |
770 | 861 | ||
771 | void error(U32 statusNum, const std::string& reason) | 862 | void error(U32 statusNum, const std::string& reason) |
772 | { | 863 | { |
773 | //throw something back to the viewer here? | 864 | //throw something back to the viewer here? |
774 | if ( gIMMgr && mIsVoiceInvitiation ) | 865 | if ( gIMMgr ) |
775 | { | 866 | { |
776 | gIMMgr->clearPendingVoiceInviation(mSessionID); | 867 | gIMMgr->clearPendingAgentListUpdates(mSessionID); |
868 | gIMMgr->clearPendingInviation(mSessionID); | ||
869 | |||
870 | LLFloaterIMPanel* floaterp = | ||
871 | gIMMgr->findFloaterBySession(mSessionID); | ||
872 | |||
873 | if ( floaterp ) | ||
874 | { | ||
875 | std::string error_string; | ||
876 | |||
877 | if ( 404 == statusNum ) | ||
878 | { | ||
879 | error_string = "does not exist"; | ||
880 | } | ||
881 | else | ||
882 | { | ||
883 | error_string = "generic"; | ||
884 | } | ||
885 | |||
886 | floaterp->showSessionStartError( | ||
887 | error_string); | ||
888 | } | ||
777 | } | 889 | } |
778 | } | 890 | } |
779 | 891 | ||
780 | private: | 892 | private: |
781 | LLUUID mSessionID; | 893 | LLUUID mSessionID; |
782 | bool mIsVoiceInvitiation; | 894 | LLIMMgr::EInvitationType mInvitiationType; |
783 | }; | 895 | }; |
784 | 896 | ||
785 | //static | 897 | //static |
@@ -807,10 +919,11 @@ void LLIMMgr::inviteUserResponse(S32 option, void* user_data) | |||
807 | im_floater->requestAutoConnect(); | 919 | im_floater->requestAutoConnect(); |
808 | LLFloaterIMPanel::onClickStartCall(im_floater); | 920 | LLFloaterIMPanel::onClickStartCall(im_floater); |
809 | // always open IM window when connecting to voice | 921 | // always open IM window when connecting to voice |
810 | LLFloaterChatterBox::showInstance(TRUE); | 922 | LLFloaterChatterBox::showInstance(invitep->mSessionID); |
811 | } | 923 | } |
812 | 924 | ||
813 | gIMMgr->clearPendingVoiceInviation(invitep->mSessionID); | 925 | gIMMgr->clearPendingAgentListUpdates(invitep->mSessionID); |
926 | gIMMgr->clearPendingInviation(invitep->mSessionID); | ||
814 | } | 927 | } |
815 | else | 928 | else |
816 | { | 929 | { |
@@ -830,34 +943,50 @@ void LLIMMgr::inviteUserResponse(S32 option, void* user_data) | |||
830 | data, | 943 | data, |
831 | new LLViewerChatterBoxInvitationAcceptResponder( | 944 | new LLViewerChatterBoxInvitationAcceptResponder( |
832 | invitep->mSessionID, | 945 | invitep->mSessionID, |
833 | true)); | 946 | invitep->mInvType)); |
834 | } | 947 | } |
835 | } | 948 | } |
836 | break; | 949 | break; |
837 | case 2: // mute (also implies ignore, so this falls through to the "ignore" case below) | 950 | case 2: // mute (also implies ignore, so this falls through to the "ignore" case below) |
951 | { | ||
952 | // mute the sender of this invite | ||
953 | if (!gMuteListp->isMuted(invitep->mCallerID)) | ||
838 | { | 954 | { |
839 | // mute the sender of this invite | 955 | LLMute mute(invitep->mCallerID, invitep->mCallerName, LLMute::AGENT); |
840 | if (!gMuteListp->isMuted(invitep->mCallerID)) | 956 | gMuteListp->add(mute); |
841 | { | ||
842 | LLMute mute(invitep->mCallerID, invitep->mCallerName, LLMute::AGENT); | ||
843 | gMuteListp->add(mute); | ||
844 | } | ||
845 | } | 957 | } |
958 | } | ||
846 | /* FALLTHROUGH */ | 959 | /* FALLTHROUGH */ |
847 | 960 | ||
848 | case 1: // ignore | 961 | case 1: // decline |
962 | { | ||
963 | if (invitep->mType == IM_SESSION_P2P_INVITE) | ||
849 | { | 964 | { |
850 | if (invitep->mType == IM_SESSION_P2P_INVITE) | 965 | if(gVoiceClient) |
851 | { | 966 | { |
852 | if(gVoiceClient) | 967 | gVoiceClient->declineInvite(invitep->mSessionHandle); |
853 | { | ||
854 | gVoiceClient->declineInvite(invitep->mSessionHandle); | ||
855 | } | ||
856 | } | 968 | } |
857 | } | 969 | } |
858 | break; | 970 | else |
971 | { | ||
972 | std::string url = gAgent.getRegion()->getCapability( | ||
973 | "ChatSessionRequest"); | ||
974 | |||
975 | LLSD data; | ||
976 | data["method"] = "decline invitation"; | ||
977 | data["session-id"] = invitep->mSessionID; | ||
978 | LLHTTPClient::post( | ||
979 | url, | ||
980 | data, | ||
981 | NULL); | ||
982 | } | ||
859 | } | 983 | } |
860 | 984 | ||
985 | gIMMgr->clearPendingAgentListUpdates(invitep->mSessionID); | ||
986 | gIMMgr->clearPendingInviation(invitep->mSessionID); | ||
987 | break; | ||
988 | } | ||
989 | |||
861 | delete invitep; | 990 | delete invitep; |
862 | } | 991 | } |
863 | 992 | ||
@@ -869,11 +998,11 @@ void LLIMMgr::setFloaterOpen(BOOL set_open) | |||
869 | { | 998 | { |
870 | if (set_open) | 999 | if (set_open) |
871 | { | 1000 | { |
872 | LLFloaterChatterBox::showInstance(LLSD()); | 1001 | LLFloaterChatterBox::showInstance(); |
873 | } | 1002 | } |
874 | else | 1003 | else |
875 | { | 1004 | { |
876 | LLFloaterChatterBox::hideInstance(LLSD()); | 1005 | LLFloaterChatterBox::hideInstance(); |
877 | } | 1006 | } |
878 | } | 1007 | } |
879 | 1008 | ||
@@ -932,11 +1061,11 @@ BOOL LLIMMgr::hasSession(const LLUUID& session_id) | |||
932 | return (findFloaterBySession(session_id) != NULL); | 1061 | return (findFloaterBySession(session_id) != NULL); |
933 | } | 1062 | } |
934 | 1063 | ||
935 | void LLIMMgr::clearPendingVoiceInviation(const LLUUID& session_id) | 1064 | void LLIMMgr::clearPendingInviation(const LLUUID& session_id) |
936 | { | 1065 | { |
937 | if ( mPendingVoiceInvitations.has(session_id.asString()) ) | 1066 | if ( mPendingInvitations.has(session_id.asString()) ) |
938 | { | 1067 | { |
939 | mPendingVoiceInvitations.erase(session_id.asString()); | 1068 | mPendingInvitations.erase(session_id.asString()); |
940 | } | 1069 | } |
941 | } | 1070 | } |
942 | 1071 | ||
@@ -958,13 +1087,57 @@ void LLIMMgr::addPendingAgentListUpdates( | |||
958 | { | 1087 | { |
959 | LLSD::map_const_iterator iter; | 1088 | LLSD::map_const_iterator iter; |
960 | 1089 | ||
961 | for ( iter = updates.beginMap(); | 1090 | if ( !mPendingAgentListUpdates.has(session_id.asString()) ) |
962 | iter != updates.endMap(); | 1091 | { |
963 | iter++) | 1092 | //this is a new agent list update for this session |
1093 | mPendingAgentListUpdates[session_id.asString()] = LLSD::emptyMap(); | ||
1094 | } | ||
1095 | |||
1096 | if ( | ||
1097 | updates.has("agent_updates") && | ||
1098 | updates["agent_updates"].isMap() && | ||
1099 | updates.has("updates") && | ||
1100 | updates["updates"].isMap() ) | ||
1101 | { | ||
1102 | //new school update | ||
1103 | LLSD update_types = LLSD::emptyArray(); | ||
1104 | LLSD::array_iterator array_iter; | ||
1105 | |||
1106 | update_types.append("agent_updates"); | ||
1107 | update_types.append("updates"); | ||
1108 | |||
1109 | for ( | ||
1110 | array_iter = update_types.beginArray(); | ||
1111 | array_iter != update_types.endArray(); | ||
1112 | ++array_iter) | ||
1113 | { | ||
1114 | //we only want to include the last update for a given agent | ||
1115 | for ( | ||
1116 | iter = updates[array_iter->asString()].beginMap(); | ||
1117 | iter != updates[array_iter->asString()].endMap(); | ||
1118 | ++iter) | ||
1119 | { | ||
1120 | mPendingAgentListUpdates[session_id.asString()][array_iter->asString()][iter->first] = | ||
1121 | iter->second; | ||
1122 | } | ||
1123 | } | ||
1124 | } | ||
1125 | else if ( | ||
1126 | updates.has("updates") && | ||
1127 | updates["updates"].isMap() ) | ||
964 | { | 1128 | { |
965 | //we only want to include the last update for a given agent | 1129 | //old school update where the SD contained just mappings |
966 | mPendingAgentListUpdates[session_id.asString()][iter->first] = | 1130 | //of agent_id -> "LEAVE"/"ENTER" |
967 | iter->second; | 1131 | |
1132 | //only want to keep last update for each agent | ||
1133 | for ( | ||
1134 | iter = updates["updates"].beginMap(); | ||
1135 | iter != updates["updates"].endMap(); | ||
1136 | ++iter) | ||
1137 | { | ||
1138 | mPendingAgentListUpdates[session_id.asString()]["updates"][iter->first] = | ||
1139 | iter->second; | ||
1140 | } | ||
968 | } | 1141 | } |
969 | } | 1142 | } |
970 | 1143 | ||
@@ -995,8 +1168,6 @@ LLFloaterIMPanel* LLIMMgr::createFloater( | |||
995 | llinfos << "LLIMMgr::createFloater: from " << other_participant_id | 1168 | llinfos << "LLIMMgr::createFloater: from " << other_participant_id |
996 | << " in session " << session_id << llendl; | 1169 | << " in session " << session_id << llendl; |
997 | LLFloaterIMPanel* floater = new LLFloaterIMPanel(session_label, | 1170 | LLFloaterIMPanel* floater = new LLFloaterIMPanel(session_label, |
998 | LLRect(), | ||
999 | session_label, | ||
1000 | session_id, | 1171 | session_id, |
1001 | other_participant_id, | 1172 | other_participant_id, |
1002 | dialog); | 1173 | dialog); |
@@ -1022,8 +1193,6 @@ LLFloaterIMPanel* LLIMMgr::createFloater( | |||
1022 | llinfos << "LLIMMgr::createFloater: from " << other_participant_id | 1193 | llinfos << "LLIMMgr::createFloater: from " << other_participant_id |
1023 | << " in session " << session_id << llendl; | 1194 | << " in session " << session_id << llendl; |
1024 | LLFloaterIMPanel* floater = new LLFloaterIMPanel(session_label, | 1195 | LLFloaterIMPanel* floater = new LLFloaterIMPanel(session_label, |
1025 | LLRect(), | ||
1026 | session_label, | ||
1027 | session_id, | 1196 | session_id, |
1028 | other_participant_id, | 1197 | other_participant_id, |
1029 | ids, | 1198 | ids, |
@@ -1034,8 +1203,9 @@ LLFloaterIMPanel* LLIMMgr::createFloater( | |||
1034 | return floater; | 1203 | return floater; |
1035 | } | 1204 | } |
1036 | 1205 | ||
1037 | void LLIMMgr::noteOfflineUsers(LLFloaterIMPanel* floater, | 1206 | void LLIMMgr::noteOfflineUsers( |
1038 | const LLDynamicArray<LLUUID>& ids) | 1207 | LLFloaterIMPanel* floater, |
1208 | const LLDynamicArray<LLUUID>& ids) | ||
1039 | { | 1209 | { |
1040 | S32 count = ids.count(); | 1210 | S32 count = ids.count(); |
1041 | if(count == 0) | 1211 | if(count == 0) |
@@ -1099,14 +1269,6 @@ LLFloaterChatterBox* LLIMMgr::getFloater() | |||
1099 | return LLFloaterChatterBox::getInstance(LLSD()); | 1269 | return LLFloaterChatterBox::getInstance(LLSD()); |
1100 | } | 1270 | } |
1101 | 1271 | ||
1102 | void onConfirmForceCloseError(S32 option, void* data) | ||
1103 | { | ||
1104 | //only 1 option really | ||
1105 | LLFloaterIMPanel* floater = ((LLFloaterIMPanel*) data); | ||
1106 | |||
1107 | if ( floater ) floater->close(FALSE); | ||
1108 | } | ||
1109 | |||
1110 | class LLViewerChatterBoxSessionStartReply : public LLHTTPNode | 1272 | class LLViewerChatterBoxSessionStartReply : public LLHTTPNode |
1111 | { | 1273 | { |
1112 | public: | 1274 | public: |
@@ -1141,7 +1303,16 @@ public: | |||
1141 | LLFloaterIMPanel* floaterp = gIMMgr->findFloaterBySession(session_id); | 1303 | LLFloaterIMPanel* floaterp = gIMMgr->findFloaterBySession(session_id); |
1142 | if (floaterp) | 1304 | if (floaterp) |
1143 | { | 1305 | { |
1144 | floaterp->setSpeakersList(body["agents"]); | 1306 | floaterp->setSpeakers(body); |
1307 | |||
1308 | //apply updates we've possibly received previously | ||
1309 | floaterp->updateSpeakersList( | ||
1310 | gIMMgr->getPendingAgentListUpdates(session_id)); | ||
1311 | |||
1312 | if ( body.has("session_info") ) | ||
1313 | { | ||
1314 | floaterp->processSessionUpdate(body["session_info"]); | ||
1315 | } | ||
1145 | 1316 | ||
1146 | //aply updates we've possibly received previously | 1317 | //aply updates we've possibly received previously |
1147 | floaterp->updateSpeakersList( | 1318 | floaterp->updateSpeakersList( |
@@ -1155,20 +1326,14 @@ public: | |||
1155 | //floater | 1326 | //floater |
1156 | LLFloaterIMPanel* floater = | 1327 | LLFloaterIMPanel* floater = |
1157 | gIMMgr->findFloaterBySession(temp_session_id); | 1328 | gIMMgr->findFloaterBySession(temp_session_id); |
1158 | if (floater) | ||
1159 | { | ||
1160 | LLString::format_map_t args; | ||
1161 | args["[REASON]"] = | ||
1162 | sErrorStringsMap[body["error"].asString()]; | ||
1163 | args["[RECIPIENT]"] = floater->getTitle(); | ||
1164 | |||
1165 | gViewerWindow->alertXml("ChatterBoxSessionStartError", | ||
1166 | args, | ||
1167 | onConfirmForceCloseError, | ||
1168 | floater); | ||
1169 | 1329 | ||
1330 | if ( floater ) | ||
1331 | { | ||
1332 | floater->showSessionStartError(body["error"].asString()); | ||
1170 | } | 1333 | } |
1171 | } | 1334 | } |
1335 | |||
1336 | gIMMgr->clearPendingAgentListUpdates(session_id); | ||
1172 | } | 1337 | } |
1173 | }; | 1338 | }; |
1174 | 1339 | ||
@@ -1200,17 +1365,12 @@ public: | |||
1200 | //throw an error dialog | 1365 | //throw an error dialog |
1201 | LLFloaterIMPanel* floater = | 1366 | LLFloaterIMPanel* floater = |
1202 | gIMMgr->findFloaterBySession(session_id); | 1367 | gIMMgr->findFloaterBySession(session_id); |
1368 | |||
1203 | if (floater) | 1369 | if (floater) |
1204 | { | 1370 | { |
1205 | LLString::format_map_t args; | 1371 | floater->showSessionEventError( |
1206 | args["[REASON]"] = | 1372 | body["event"].asString(), |
1207 | sErrorStringsMap[body["error"].asString()]; | 1373 | body["error"].asString()); |
1208 | args["[EVENT]"] = | ||
1209 | sEventStringsMap[body["event"].asString()]; | ||
1210 | args["[RECIPIENT]"] = floater->getTitle(); | ||
1211 | |||
1212 | gViewerWindow->alertXml("ChatterBoxSessionEventError", | ||
1213 | args); | ||
1214 | } | 1374 | } |
1215 | } | 1375 | } |
1216 | } | 1376 | } |
@@ -1234,15 +1394,7 @@ public: | |||
1234 | 1394 | ||
1235 | if ( floater ) | 1395 | if ( floater ) |
1236 | { | 1396 | { |
1237 | LLString::format_map_t args; | 1397 | floater->showSessionForceClose(reason); |
1238 | |||
1239 | args["[NAME]"] = floater->getTitle(); | ||
1240 | args["[REASON]"] = sForceCloseSessionMap[reason]; | ||
1241 | |||
1242 | gViewerWindow->alertXml("ForceCloseChatterBoxSession", | ||
1243 | args, | ||
1244 | onConfirmForceCloseError, | ||
1245 | floater); | ||
1246 | } | 1398 | } |
1247 | } | 1399 | } |
1248 | }; | 1400 | }; |
@@ -1258,7 +1410,8 @@ public: | |||
1258 | LLFloaterIMPanel* floaterp = gIMMgr->findFloaterBySession(input["body"]["session_id"].asUUID()); | 1410 | LLFloaterIMPanel* floaterp = gIMMgr->findFloaterBySession(input["body"]["session_id"].asUUID()); |
1259 | if (floaterp) | 1411 | if (floaterp) |
1260 | { | 1412 | { |
1261 | floaterp->updateSpeakersList(input["body"]["updates"]); | 1413 | floaterp->updateSpeakersList( |
1414 | input["body"]); | ||
1262 | } | 1415 | } |
1263 | else | 1416 | else |
1264 | { | 1417 | { |
@@ -1267,11 +1420,28 @@ public: | |||
1267 | //a start or an acceptance of an invitation. Race condition. | 1420 | //a start or an acceptance of an invitation. Race condition. |
1268 | gIMMgr->addPendingAgentListUpdates( | 1421 | gIMMgr->addPendingAgentListUpdates( |
1269 | input["body"]["session_id"].asUUID(), | 1422 | input["body"]["session_id"].asUUID(), |
1270 | input["body"]["updates"]); | 1423 | input["body"]); |
1271 | } | 1424 | } |
1272 | } | 1425 | } |
1273 | }; | 1426 | }; |
1274 | 1427 | ||
1428 | class LLViewerChatterBoxSessionUpdate : public LLHTTPNode | ||
1429 | { | ||
1430 | public: | ||
1431 | virtual void post( | ||
1432 | ResponsePtr responder, | ||
1433 | const LLSD& context, | ||
1434 | const LLSD& input) const | ||
1435 | { | ||
1436 | LLFloaterIMPanel* floaterp = gIMMgr->findFloaterBySession(input["body"]["session_id"].asUUID()); | ||
1437 | if (floaterp) | ||
1438 | { | ||
1439 | floaterp->processSessionUpdate(input["body"]["info"]); | ||
1440 | } | ||
1441 | } | ||
1442 | }; | ||
1443 | |||
1444 | |||
1275 | class LLViewerChatterBoxInvitation : public LLHTTPNode | 1445 | class LLViewerChatterBoxInvitation : public LLHTTPNode |
1276 | { | 1446 | { |
1277 | public: | 1447 | public: |
@@ -1281,10 +1451,10 @@ public: | |||
1281 | const LLSD& context, | 1451 | const LLSD& context, |
1282 | const LLSD& input) const | 1452 | const LLSD& input) const |
1283 | { | 1453 | { |
1454 | //for backwards compatiblity reasons...we need to still | ||
1455 | //check for 'text' or 'voice' invitations...bleh | ||
1284 | if ( input["body"].has("instantmessage") ) | 1456 | if ( input["body"].has("instantmessage") ) |
1285 | { | 1457 | { |
1286 | LLString capability = input["body"]["capabilities"]["call"].asString(); | ||
1287 | |||
1288 | LLSD message_params = | 1458 | LLSD message_params = |
1289 | input["body"]["instantmessage"]["message_params"]; | 1459 | input["body"]["instantmessage"]["message_params"]; |
1290 | 1460 | ||
@@ -1392,13 +1562,13 @@ public: | |||
1392 | { | 1562 | { |
1393 | LLSD data; | 1563 | LLSD data; |
1394 | data["method"] = "accept invitation"; | 1564 | data["method"] = "accept invitation"; |
1395 | data["session-id"] = input["body"]["session_id"]; | 1565 | data["session-id"] = session_id; |
1396 | LLHTTPClient::post( | 1566 | LLHTTPClient::post( |
1397 | url, | 1567 | url, |
1398 | data, | 1568 | data, |
1399 | new LLViewerChatterBoxInvitationAcceptResponder( | 1569 | new LLViewerChatterBoxInvitationAcceptResponder( |
1400 | input["body"]["session_id"], | 1570 | session_id, |
1401 | false)); | 1571 | LLIMMgr::INVITATION_TYPE_INSTANT_MESSAGE)); |
1402 | } | 1572 | } |
1403 | } //end if invitation has instant message | 1573 | } //end if invitation has instant message |
1404 | else if ( input["body"].has("voice") ) | 1574 | else if ( input["body"].has("voice") ) |
@@ -1419,7 +1589,18 @@ public: | |||
1419 | input["body"]["session_name"].asString(), | 1589 | input["body"]["session_name"].asString(), |
1420 | input["body"]["from_id"].asUUID(), | 1590 | input["body"]["from_id"].asUUID(), |
1421 | input["body"]["from_name"].asString(), | 1591 | input["body"]["from_name"].asString(), |
1422 | IM_SESSION_INVITE); | 1592 | IM_SESSION_INVITE, |
1593 | LLIMMgr::INVITATION_TYPE_VOICE); | ||
1594 | } | ||
1595 | else if ( input["body"].has("immediate") ) | ||
1596 | { | ||
1597 | gIMMgr->inviteToSession( | ||
1598 | input["body"]["session_id"].asUUID(), | ||
1599 | input["body"]["session_name"].asString(), | ||
1600 | input["body"]["from_id"].asUUID(), | ||
1601 | input["body"]["from_name"].asString(), | ||
1602 | IM_SESSION_INVITE, | ||
1603 | LLIMMgr::INVITATION_TYPE_IMMEDIATE); | ||
1423 | } | 1604 | } |
1424 | } | 1605 | } |
1425 | }; | 1606 | }; |
@@ -1440,6 +1621,10 @@ LLHTTPRegistration<LLViewerChatterBoxSessionAgentListUpdates> | |||
1440 | gHTTPRegistrationMessageChatterboxsessionagentlistupdates( | 1621 | gHTTPRegistrationMessageChatterboxsessionagentlistupdates( |
1441 | "/message/ChatterBoxSessionAgentListUpdates"); | 1622 | "/message/ChatterBoxSessionAgentListUpdates"); |
1442 | 1623 | ||
1624 | LLHTTPRegistration<LLViewerChatterBoxSessionUpdate> | ||
1625 | gHTTPRegistrationMessageChatterBoxSessionUpdate( | ||
1626 | "/message/ChatterBoxSessionUpdate"); | ||
1627 | |||
1443 | LLHTTPRegistration<LLViewerChatterBoxInvitation> | 1628 | LLHTTPRegistration<LLViewerChatterBoxInvitation> |
1444 | gHTTPRegistrationMessageChatterBoxInvitation( | 1629 | gHTTPRegistrationMessageChatterBoxInvitation( |
1445 | "/message/ChatterBoxInvitation"); | 1630 | "/message/ChatterBoxInvitation"); |