void HippoChatRoomWrapper::notifyMessage(HippoChatMessage *message) { HippoPerson *user; user = hippo_chat_message_get_person(message); for (unsigned long i = 0; i < listeners_.length(); i++) listeners_[i]->onMessage(this, message); HippoPtr<IConnectionPoint> point; if (FAILED(connectionPointContainer_.FindConnectionPoint(__uuidof(IHippoChatRoomEvents), &point))) return; HippoPtr<IEnumConnections> e; if (FAILED(point->EnumConnections(&e))) return; HippoBSTR name = HippoBSTR::fromUTF8(hippo_entity_get_name(HIPPO_ENTITY(user)), -1); HippoBSTR guid = HippoBSTR::fromUTF8(hippo_entity_get_guid(HIPPO_ENTITY(user)), -1); HippoBSTR photoUrl = HippoBSTR::fromUTF8(hippo_entity_get_small_photo_url(HIPPO_ENTITY(user)), -1); HippoBSTR text = HippoBSTR::fromUTF8(hippo_chat_message_get_text(message), -1); CONNECTDATA data; ULONG fetched; while (e->Next(1, &data, &fetched) == S_OK) { HippoQIPtr<IDispatch> dispatch(data.pUnk); if (dispatch) { DISPPARAMS dispParams; VARIANTARG args[6]; args[0].vt = VT_INT; args[0].intVal = hippo_chat_message_get_serial(message); args[1].vt = VT_R8; args[1].dblVal = (DOUBLE)hippo_chat_message_get_timestamp(message); args[2].vt = VT_BSTR; args[2].bstrVal = text.m_str; args[3].vt = VT_BSTR; args[3].bstrVal = name.m_str; args[4].vt = VT_BSTR; args[4].bstrVal = photoUrl.m_str; args[5].vt = VT_BSTR; args[5].bstrVal = guid.m_str; dispParams.rgvarg = args; dispParams.cArgs = 6; dispParams.cNamedArgs = 0; dispParams.rgdispidNamedArgs = NULL; HRESULT hr = dispatch->Invoke(HIPPO_DISPID_ONMESSAGE, IID_NULL, 0 /* LCID */, DISPATCH_METHOD, &dispParams, NULL /* result */, NULL /* exception */, NULL /* argError */); if (!SUCCEEDED(hr)) hippoDebugDialog(L"OnMessage invoke failed %x", hr); } } }
void hippo_actions_invite_to_group(HippoActions *actions, HippoGroup *group, HippoPerson *person) { hippo_connection_do_invite_to_group(get_connection(actions), hippo_entity_get_guid(HIPPO_ENTITY(group)), hippo_entity_get_guid(HIPPO_ENTITY(person))); }
void hippo_actions_invite_to_group(HippoActions *actions, HippoGroup *group, HippoPerson *person) { ddm_data_model_update(actions->model, "http://mugshot.org/p/groups#inviteUser", NULL, "groupId", hippo_entity_get_guid(HIPPO_ENTITY(group)), "userId", hippo_entity_get_guid(HIPPO_ENTITY(person)), NULL); }
void HippoChatRoomWrapper::notifyUserJoin(HippoPerson *user) { for (unsigned long i = 0; i < listeners_.length(); i++) listeners_[i]->onUserJoin(this, user); HippoPtr<IConnectionPoint> point; if (FAILED(connectionPointContainer_.FindConnectionPoint(__uuidof(IHippoChatRoomEvents), &point))) return; HippoPtr<IEnumConnections> e; if (FAILED(point->EnumConnections(&e))) return; HippoChatState state = hippo_chat_room_get_user_state(delegate_, user); g_return_if_fail(state != HIPPO_CHAT_STATE_NONMEMBER); HippoBSTR name = HippoBSTR::fromUTF8(hippo_entity_get_name(HIPPO_ENTITY(user)), -1); HippoBSTR guid = HippoBSTR::fromUTF8(hippo_entity_get_guid(HIPPO_ENTITY(user)), -1); HippoBSTR photoUrl = HippoBSTR::fromUTF8(hippo_entity_get_small_photo_url(HIPPO_ENTITY(user)), -1); CONNECTDATA data; ULONG fetched; while (e->Next(1, &data, &fetched) == S_OK) { HippoQIPtr<IDispatch> dispatch(data.pUnk); if (dispatch) { DISPPARAMS dispParams; VARIANTARG args[4]; args[0].vt = VT_BOOL; args[0].boolVal = state == HIPPO_CHAT_STATE_PARTICIPANT ? TRUE : FALSE; args[1].vt = VT_BSTR; args[1].bstrVal = name.m_str; args[2].vt = VT_BSTR; args[2].bstrVal = photoUrl.m_str; args[3].vt = VT_BSTR; args[3].bstrVal = guid.m_str; dispParams.rgvarg = args; dispParams.cArgs = 4; dispParams.cNamedArgs = 0; dispParams.rgdispidNamedArgs = NULL; HRESULT hr = dispatch->Invoke(HIPPO_DISPID_ONUSERJOIN, IID_NULL, 0 /* LCID */, DISPATCH_METHOD, &dispParams, NULL /* result */, NULL /* exception */, NULL /* argError */); if (!SUCCEEDED(hr)) hippoDebugDialog(L"OnUserJoin invoke failed %x", hr); } } }
static void on_group_changed(HippoBlock *block, GParamSpec *arg, /* null when first calling this */ HippoCanvasBlock *canvas_block) { HippoGroup *group; HippoCanvasBlockGroupChat *canvas_group_chat; canvas_group_chat = HIPPO_CANVAS_BLOCK_GROUP_CHAT(canvas_block); g_assert(block == canvas_block->block); group = NULL; g_object_get(G_OBJECT(block), "group", &group, NULL); if (group == NULL) { /* can't think of much sensible to do here, presumably it will * get set back to non-null later */ } else { update_chat_messages(canvas_group_chat); hippo_canvas_block_set_sender(HIPPO_CANVAS_BLOCK(canvas_group_chat), hippo_entity_get_guid(HIPPO_ENTITY(group))); g_object_unref(group); } }
void HippoChatRoomWrapper::notifyUserChange(HippoPerson *person) { // FIXME if user is only viewing, skip this // FIXME this is historically only about music changing ... should be modified // to include also the name and photo so those will update for (unsigned long i = 0; i < listeners_.length(); i++) listeners_[i]->onUserChange(this, person); HippoPtr<IConnectionPoint> point; if (FAILED(connectionPointContainer_.FindConnectionPoint(__uuidof(IHippoChatRoomEvents), &point))) return; HippoPtr<IEnumConnections> e; if (FAILED(point->EnumConnections(&e))) return; HippoBSTR artist = HippoBSTR::fromUTF8(hippo_person_get_current_artist(person), -1); HippoBSTR song = HippoBSTR::fromUTF8(hippo_person_get_current_song(person), -1); HippoBSTR guid = HippoBSTR::fromUTF8(hippo_entity_get_guid(HIPPO_ENTITY(person)), -1); CONNECTDATA data; ULONG fetched; while (e->Next(1, &data, &fetched) == S_OK) { HippoQIPtr<IDispatch> dispatch(data.pUnk); if (dispatch) { DISPPARAMS dispParams; VARIANTARG args[4]; // order of these arguments gets reversed, so we need to supply // the musicPlaying flag as the first argument, and the userId as the last one args[0].vt = VT_BOOL; args[0].boolVal = hippo_person_get_music_playing(person); args[1].vt = VT_BSTR; args[1].bstrVal = artist.m_str; args[2].vt = VT_BSTR; args[2].bstrVal = song.m_str; args[3].vt = VT_BSTR; args[3].bstrVal = guid.m_str; dispParams.rgvarg = args; dispParams.cArgs = 4; dispParams.cNamedArgs = 0; dispParams.rgdispidNamedArgs = NULL; HRESULT hr = dispatch->Invoke(HIPPO_DISPID_ONUSERMUSICCHANGE, IID_NULL, 0 /* LCID */, DISPATCH_METHOD, &dispParams, NULL /* result */, NULL /* exception */, NULL /* argError */); if (!SUCCEEDED(hr)) hippoDebugDialog(L"OnUserChange invoke failed %x", hr); } } }
void hippo_group_set_chat_room(HippoGroup *group, HippoChatRoom *room) { g_return_if_fail(HIPPO_IS_GROUP(group)); if (room == group->room) return; if (room) g_object_ref(room); if (group->room) g_object_unref(group->room); group->room = room; if (group->room) hippo_chat_room_set_title(group->room, hippo_entity_get_name(HIPPO_ENTITY(group))); hippo_entity_notify(HIPPO_ENTITY(group)); }
void hippo_group_set_date_last_ignored(HippoGroup *group, GTime date) { g_return_if_fail(HIPPO_IS_GROUP(group)); if (group->date_last_ignored != date) { group->date_last_ignored = date; hippo_entity_notify(HIPPO_ENTITY(group)); } }
static void update_caches(HippoPersonRenderer *renderer, GtkWidget *widget) { const char *name; const char *song; const char *artist; GtkIconTheme *icon_theme; GdkPixbuf *note_on; GdkPixbuf *note_off; if (renderer->person == NULL) { name = NULL; song = NULL; artist = NULL; } else { /* some of these can return NULL */ name = hippo_entity_get_name(HIPPO_ENTITY(renderer->person)); song = hippo_person_get_current_song(renderer->person); artist = hippo_person_get_current_artist(renderer->person); } make_layout(widget, &renderer->name_layout, name); /* FIXME better to omit the note and the space for music * entirely, but this keeps it from looking broken for now */ if (song == NULL || *song == '\0') song = _("No song"); make_layout(widget, &renderer->song_layout, song); make_layout(widget, &renderer->artist_layout, artist); /* this strongly relies on the icon theme caching the pixbufs * so it typically ends up as a no-op */ icon_theme = gtk_icon_theme_get_for_screen(gtk_widget_get_screen(widget)); note_on = gtk_icon_theme_load_icon(icon_theme, "mugshot_note_on", NOTE_SIZE, 0, NULL); note_off = gtk_icon_theme_load_icon(icon_theme, "mugshot_note_on", NOTE_SIZE, 0, NULL); if (note_on) { if (renderer->note_on) g_object_unref(renderer->note_on); renderer->note_on = note_on; } if (note_off) { if (renderer->note_off) g_object_unref(renderer->note_off); renderer->note_off = note_off; } }
static void on_user_changed(HippoBlock *block, GParamSpec *arg, /* null when first calling this */ HippoCanvasBlockMusic *block_music) { HippoPerson *person; person = NULL; g_object_get(G_OBJECT(block), "user", &person, NULL); hippo_canvas_block_set_sender(HIPPO_CANVAS_BLOCK(block_music), person ? hippo_entity_get_guid(HIPPO_ENTITY(person)) : NULL); if (person) g_object_unref(person); }
STDMETHODIMP HippoPostWrapper::get_LastChatSender(IHippoEntity **sender) { *sender = NULL; HippoChatRoom *room = hippo_post_get_chat_room(delegate_); if (room) { HippoChatMessage *m = hippo_chat_room_get_last_message(room); if (m != NULL) { HippoPerson *person = hippo_chat_message_get_person(m); if (person != NULL) entityToCom(HIPPO_ENTITY(person), sender); } } return S_OK; }
void HippoListenerProxyImpl::onMessage(HippoChatRoom *room, HippoChatMessage *message, HippoEndpointProxy *endpointProxy) { HippoPerson *sender = hippo_chat_message_get_person(message); HippoBSTR chatId = HippoBSTR::fromUTF8(hippo_chat_room_get_id(room), -1); HippoBSTR entityId = HippoBSTR::fromUTF8(hippo_entity_get_guid(HIPPO_ENTITY(sender)), -1); HippoBSTR text = HippoBSTR::fromUTF8(hippo_chat_message_get_text(message), -1); if (listener_) listener_->OnMessage(hippo_endpoint_proxy_get_id(endpointProxy), chatId, entityId, text, hippo_chat_message_get_timestamp(message), hippo_chat_message_get_serial(message)); }
static void set_person(HippoCanvasBlockFacebookEvent *block_facebook_event, HippoPerson *person) { if (person == block_facebook_event->person) return; if (block_facebook_event->person) { g_object_unref(block_facebook_event->person); block_facebook_event->person = NULL; } if (person) { block_facebook_event->person = person; g_object_ref(G_OBJECT(person)); } hippo_canvas_block_set_sender(HIPPO_CANVAS_BLOCK(block_facebook_event), person ? hippo_entity_get_guid(HIPPO_ENTITY(person)) : NULL); }
HippoChatState hippo_chat_room_get_user_state(HippoChatRoom *room, HippoPerson *person) { HippoChatState state; const char *guid; g_return_val_if_fail(HIPPO_IS_CHAT_ROOM(room), HIPPO_CHAT_STATE_NONMEMBER); guid = hippo_entity_get_guid(HIPPO_ENTITY(person)); if (g_hash_table_lookup(room->viewers, guid) != NULL) state = HIPPO_CHAT_STATE_VISITOR; else if (g_hash_table_lookup(room->chatters, guid) != NULL) state = HIPPO_CHAT_STATE_PARTICIPANT; else state = HIPPO_CHAT_STATE_NONMEMBER; return state; }
static void set_person(HippoCanvasBlockNetflixMovie *block_netflix, HippoPerson *person) { if (person == block_netflix->person) return; if (block_netflix->person) { g_object_unref(block_netflix->person); block_netflix->person = NULL; } if (person) { block_netflix->person = person; g_object_ref(G_OBJECT(person)); } hippo_canvas_block_set_sender(HIPPO_CANVAS_BLOCK(block_netflix), person ? hippo_entity_get_guid(HIPPO_ENTITY(person)) : NULL); }
static void notification_is_needed_callback(HippoCanvasItem *item, void *data) { NotificationNeededInfo *info = data; gboolean notify_for_block = TRUE; HippoBlock *block; g_object_get(G_OBJECT(item), "block", &block, NULL); g_debug("Checking if notification is needed for block %s\n", hippo_block_get_guid(block)); if (HIPPO_IS_BLOCK_POST(block)) { HippoPost *post; g_object_get(G_OBJECT(block), "post", &post, NULL); if (post) { if (chat_is_visible(info->manager, hippo_post_get_guid(post))) notify_for_block = FALSE; g_object_unref(post); } } else if (HIPPO_IS_BLOCK_GROUP_CHAT(block)) { HippoGroup *group; g_object_get(G_OBJECT(block), "group", &group, NULL); if (group) { if (chat_is_visible(info->manager, hippo_entity_get_guid(HIPPO_ENTITY(group)))) notify_for_block = FALSE; g_object_unref(group); } } else if (block->type == HIPPO_BLOCK_TYPE_MUSIC_CHAT) { if (chat_is_visible(info->manager, hippo_block_get_chat_id(block))) notify_for_block = FALSE; } g_object_unref(block); if (notify_for_block) info->is_needed = TRUE; }
void HippoChatRoomWrapper::notifyUserLeave(HippoPerson *user) { for (unsigned long j = 0; j < listeners_.length(); j++) listeners_[j]->onUserLeave(this, user); HippoPtr<IConnectionPoint> point; if (FAILED(connectionPointContainer_.FindConnectionPoint(__uuidof(IHippoChatRoomEvents), &point))) return; HippoPtr<IEnumConnections> e; if (FAILED(point->EnumConnections(&e))) return; HippoBSTR guid = HippoBSTR::fromUTF8(hippo_entity_get_guid(HIPPO_ENTITY(user)), -1); CONNECTDATA data; ULONG fetched; while (e->Next(1, &data, &fetched) == S_OK) { HippoQIPtr<IDispatch> dispatch(data.pUnk); if (dispatch) { DISPPARAMS dispParams; VARIANTARG args[1]; args[0].vt = VT_BSTR; args[0].bstrVal = guid.m_str; dispParams.rgvarg = args; dispParams.cArgs = 1; dispParams.cNamedArgs = 0; dispParams.rgdispidNamedArgs = NULL; HRESULT hr = dispatch->Invoke(HIPPO_DISPID_ONUSERLEAVE, IID_NULL, 0 /* LCID */, DISPATCH_METHOD, &dispParams, NULL /* result */, NULL /* exception */, NULL /* argError */); if (!SUCCEEDED(hr)) hippoDebugDialog(L"Invoke failed %x", hr); } } }
STDMETHODIMP HippoPostWrapper::get_Viewers(IHippoEntityCollection **viewers) { if (!viewers_) { // create viewers object viewers_ = new HippoEntityCollection(); viewers_->Release(); // the smart pointer has got it // this list isn't copied, no need to free it GSList *cRecipients = hippo_post_get_viewers(delegate_); for (GSList *link = cRecipients; link != NULL; link = link->next) { HippoEntity *r = HIPPO_ENTITY(link->data); viewers_->addMember(r); } } viewers_->AddRef(); *viewers = viewers_; return S_OK; }
static void hippo_canvas_block_group_chat_title_activated(HippoCanvasBlock *canvas_block) { HippoActions *actions; HippoGroup *group; if (canvas_block->block == NULL) return; actions = hippo_canvas_block_get_actions(canvas_block); group = NULL; g_object_get(G_OBJECT(canvas_block->block), "group", &group, NULL); if (group == NULL) return; hippo_actions_join_chat_id(actions, hippo_entity_get_guid(HIPPO_ENTITY(group))); g_object_unref(group); }
STDMETHODIMP HippoPostWrapper::get_CurrentViewers(IHippoEntityCollection **viewers) { // We keep a pointer to the CurrentViewers object so something like // for (i = 0; i < post.CurrentViewers.length; i++) { ... } // doesn't continually create new objects, but we don't try to // incrementally update it, we just clear it and demand create // a new one. if (!currentViewers_) { currentViewers_ = new HippoEntityCollection(); currentViewers_->Release(); // the smart pointer has got it HippoChatRoom *room = hippo_post_get_chat_room(delegate_); if (room) { GSList *members = hippo_chat_room_get_users(room); for (GSList *link = members; link != NULL; link = link->next) { HippoEntity *entity = HIPPO_ENTITY(link->data); currentViewers_->addMember(entity); g_object_unref(entity); } g_slist_free(members); // connect up to clear cache if chat room changes userStateChanged_.connect(G_OBJECT(room), "user-state-changed", slot(this, &HippoPostWrapper::onUserStateChanged)); cleared_.connect(G_OBJECT(room), "cleared", slot(this, &HippoPostWrapper::onCleared)); } } currentViewers_->AddRef(); *viewers = currentViewers_; return S_OK; }
void hippo_chat_room_set_user_state(HippoChatRoom *room, HippoPerson *person, HippoChatState state) { HippoChatState old_state; const char *guid; g_return_if_fail(HIPPO_IS_CHAT_ROOM(room)); old_state = hippo_chat_room_get_user_state(room, person); g_debug("Updating chat state room '%s' person '%s/%s' old state %d state %d", room->id, hippo_entity_get_guid(HIPPO_ENTITY(person)), hippo_entity_get_name(HIPPO_ENTITY(person)) ? hippo_entity_get_name(HIPPO_ENTITY(person)) : "NULL", old_state, state); if (old_state == state) return; guid = hippo_entity_get_guid(HIPPO_ENTITY(person)); /* so we can remove from our hash tables and then * still safely emit the signal */ g_object_ref(person); switch (old_state) { case HIPPO_CHAT_STATE_VISITOR: g_hash_table_remove(room->viewers, guid); break; case HIPPO_CHAT_STATE_PARTICIPANT: g_hash_table_remove(room->chatters, guid); break; case HIPPO_CHAT_STATE_NONMEMBER: /* no old entry to remove */ break; } switch(state) { case HIPPO_CHAT_STATE_VISITOR: g_object_ref(person); /* extra ref for the hash */ g_hash_table_replace(room->viewers, g_strdup(guid), person); break; case HIPPO_CHAT_STATE_PARTICIPANT: g_object_ref(person); /* extra ref for the hash */ g_hash_table_replace(room->chatters, g_strdup(guid), person); break; case HIPPO_CHAT_STATE_NONMEMBER: /* no new entry to insert */ break; } g_signal_emit(room, signals[USER_STATE_CHANGED], 0, person); if (!room->loading && old_state == HIPPO_CHAT_STATE_NONMEMBER) { g_signal_emit(room, signals[USER_JOINED], 0, person); } g_object_unref(person); }
static void update_chat_messages(HippoCanvasBlockGroupChat *canvas_group_chat) { HippoGroup *group; HippoBlock *block; HippoCanvasBlock *canvas_block; HippoChatMessage *last_message = NULL; HippoChatRoom *room; canvas_block = HIPPO_CANVAS_BLOCK(canvas_group_chat); block = canvas_block->block; g_assert(block != NULL); group = NULL; g_object_get(G_OBJECT(block), "group", &group, NULL); if (group == NULL) { /* should only happen transiently if at all */ /* unset all the chat preview */ g_object_set(G_OBJECT(canvas_group_chat->chat_preview), "chat-id", NULL, "chat-room", NULL, NULL); return; } /* FIXME the title should probably be something like "N people chatting" or * "N messages" but we don't have that info yet */ hippo_canvas_block_set_title(HIPPO_CANVAS_BLOCK(canvas_group_chat), "New chat activity", "Click to join group chat"); /* For the chat preview, prefer to use the chat room if * we have one, otherwise use the static recent messages * summary. */ room = hippo_group_get_chat_room(group); g_object_set(G_OBJECT(canvas_group_chat->chat_preview), "chat-id", hippo_entity_get_guid(HIPPO_ENTITY(group)), "chat-room", room, NULL); if (room) { last_message = hippo_chat_room_get_last_message(room); } else { /* We need to use recent messages summary from the block instead */ GSList *messages; g_object_get(G_OBJECT(block), "recent-messages", &messages, NULL); if (messages) last_message = messages->data; while (messages) { g_object_set(G_OBJECT(canvas_group_chat->chat_preview), "recent-message", messages->data, NULL); messages = messages->next; } } g_object_set(G_OBJECT(canvas_group_chat->single_message_preview), "message", last_message, NULL); canvas_group_chat->have_messages = last_message != NULL; hippo_canvas_block_group_update_visibility(canvas_group_chat); g_object_unref(group); }