summaryrefslogtreecommitdiff
path: root/plugins/MessageState/src/messagestate.cpp
blob: 99e47ced00b7ac19051132fedfc192b75dd62e88 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#include "stdafx.h"

static HANDLE hExtraIcon = nullptr;

int ExtraIconsApply(WPARAM hContact, LPARAM force)
{
	if (hContact != 0) {
		if (HasUnread(hContact) || force)
			ExtraIcon_SetIcon(hExtraIcon, hContact, g_plugin.getIconHandle(IDI_EXTRA));
		else
			ExtraIcon_Clear(hExtraIcon, hContact);
	}

	return 0;
}

/////////////////////////////////////////////////////////////////////////////////////////

void SetSRMMIcon(MCONTACT hContact, int iconId, time_t time)
{
	auto *p = FindContact(hContact);

	const wchar_t *pwszToolTip;
	switch (iconId) {
	case IDI_READ:
		// if that contact was never marked as read
		if (p->type != -1) { 
			wchar_t buf[100];
			wcsftime(buf, _countof(buf), TranslateT("Last message read at %X %x"), localtime(&time));
			pwszToolTip = buf;
		}
		else pwszToolTip = TranslateT("Last message read");
		break;

	case IDI_UNREAD: pwszToolTip = TranslateT("Last message is not read"); break;
	case IDI_FAIL:   pwszToolTip = TranslateT("Last message was not sent"); break;
	case IDI_NOSENT: pwszToolTip = TranslateT("Sending..."); break;
	default:         pwszToolTip = nullptr;
	}

	Srmm_ModifyIcon(hContact, MODULENAME, 1, g_plugin.getIcon(iconId), pwszToolTip);
}

void IconsUpdate(MCONTACT hContact)
{
	auto *p = FindContact(hContact);

	// if we've did nothing with this contact, leave its icon hidden
	if (p->type == -1)
		return;

	// if that's the first time we show an icon, unhide it first
	if (p->bHidden) {
		p->bHidden = false;
		Srmm_SetIconFlags(hContact, MODULENAME, 1, 0);
	}

	SetSRMMIcon(hContact, p->type == MRD_TYPE_DELIVERED ? IDI_UNREAD : IDI_READ, p->dwLastReadTime);

	ExtraIconsApply(hContact, 0);

	if (db_mc_isSub(hContact))
		IconsUpdate(db_mc_getMeta(hContact));
}

static int OnProtoAck(WPARAM, LPARAM lParam)
{
	ACKDATA *pAck = (ACKDATA *)lParam;
	if (pAck && (pAck->type == ACKTYPE_MESSAGE || pAck->type == ACKTYPE_FILE) && CheckProtoSupport(pAck->szModule)) {
		if (pAck->result == ACKRESULT_SUCCESS)
			SetSRMMIcon(pAck->hContact, IDI_NOSENT);
		else if (pAck->result == ACKRESULT_FAILED)
			SetSRMMIcon(pAck->hContact, IDI_FAIL);

		ExtraIconsApply(pAck->hContact, 0);
	}
	return 0;
}

static int OnEventFilterAdd(WPARAM hContact, LPARAM lParam)
{
	DBEVENTINFO *dbei = (DBEVENTINFO *)lParam;
	if ((dbei->flags & DBEF_SENT) && CheckProtoSupport(dbei->szModule)) {
		__time64_t dwTime = GetPreciousTime();
		FindContact(hContact)->setSent(dwTime);
		if (db_mc_isSub(hContact))
			FindContact(db_mc_getMeta(hContact))->setSent(dwTime);

		SetSRMMIcon(hContact, IDI_NOSENT);
	}
	return 0;
}

static int OnSrmmWindowOpened(WPARAM, LPARAM lParam)
{
	auto *pEvent = (MessageWindowEventData*)lParam;
	if (pEvent->uType == MSG_WINDOW_EVT_OPENING)
		IconsUpdate(pEvent->hContact);
	return 0;
}

static int OnMetaChanged(WPARAM hContact, LPARAM)
{
	IconsUpdate(hContact);
	return 0;
}

int OnModulesLoaded(WPARAM, LPARAM)
{
	hExtraIcon = ExtraIcon_RegisterIcolib("messagestate_unread", LPGEN("MessageState unread extra icon"), "clist_unread_icon");

	HookEvent(ME_PROTO_ACK, OnProtoAck);
	HookEvent(ME_DB_EVENT_FILTER_ADD, OnEventFilterAdd);
	HookEvent(ME_MC_DEFAULTTCHANGED, OnMetaChanged);
	HookEvent(ME_MC_SUBCONTACTSCHANGED, OnMetaChanged);
	HookEvent(ME_MSG_WINDOWEVENT, OnSrmmWindowOpened);
	HookEvent(ME_CLIST_EXTRA_IMAGE_APPLY, ExtraIconsApply);

	StatusIconData sid = {};
	sid.szModule = MODULENAME;
	sid.flags = MBF_HIDDEN;
	sid.dwId = 1;
	Srmm_AddIcon(&sid, &g_plugin);
	return 0;
}