From e3e89f1237a1adc7bf71824c113e4ad7c5d34cfe Mon Sep 17 00:00:00 2001 From: George Hazan Date: Mon, 2 Sep 2024 20:42:37 +0300 Subject: fixes #4595 (despite custom icons) --- protocols/SkypeWeb/src/main.cpp | 1 - protocols/SkypeWeb/src/requests/status.h | 12 -- protocols/SkypeWeb/src/resource.h | 17 +-- protocols/SkypeWeb/src/skype_menus.cpp | 12 +- protocols/SkypeWeb/src/skype_menus.h | 6 - protocols/SkypeWeb/src/skype_mood.cpp | 145 ++++++++++++++++++++++ protocols/SkypeWeb/src/skype_profile.cpp | 205 +------------------------------ protocols/SkypeWeb/src/skype_proto.cpp | 38 +----- protocols/SkypeWeb/src/skype_proto.h | 25 ++-- protocols/SkypeWeb/src/skype_utils.cpp | 62 +++++++--- protocols/SkypeWeb/src/skype_utils.h | 5 +- protocols/SkypeWeb/src/stdafx.h | 1 + 12 files changed, 235 insertions(+), 294 deletions(-) create mode 100644 protocols/SkypeWeb/src/skype_mood.cpp (limited to 'protocols/SkypeWeb/src') diff --git a/protocols/SkypeWeb/src/main.cpp b/protocols/SkypeWeb/src/main.cpp index cd3cd257da..d508708754 100644 --- a/protocols/SkypeWeb/src/main.cpp +++ b/protocols/SkypeWeb/src/main.cpp @@ -66,7 +66,6 @@ int CMPlugin::Load() CSkypeProto::InitIcons(); CSkypeProto::InitMenus(); - CSkypeProto::InitLanguages(); CreateServiceFunction(MODULE "/GetEventIcon", &CSkypeProto::SvcEventGetIcon); CreateServiceFunction(MODULE "/GetEventText", &CSkypeProto::SvcGetEventText); diff --git a/protocols/SkypeWeb/src/requests/status.h b/protocols/SkypeWeb/src/requests/status.h index 777465935a..ba07bd7156 100644 --- a/protocols/SkypeWeb/src/requests/status.h +++ b/protocols/SkypeWeb/src/requests/status.h @@ -29,16 +29,4 @@ struct SetStatusRequest : public AsyncHttpRequest } }; -struct SetStatusMsgRequest : public AsyncHttpRequest -{ - SetStatusMsgRequest(const char *status) : - AsyncHttpRequest(REQUEST_POST, HOST_API, "/users/self/profile/partial") - { - JSONNode node, payload; - payload.set_name("payload"); - node << (payload << CHAR_PARAM("mood", status)); - m_szParam = node.write().c_str(); - } -}; - #endif //_SKYPE_REQUEST_STATUS_H_ diff --git a/protocols/SkypeWeb/src/resource.h b/protocols/SkypeWeb/src/resource.h index 206b116668..2fc0d57719 100644 --- a/protocols/SkypeWeb/src/resource.h +++ b/protocols/SkypeWeb/src/resource.h @@ -1,15 +1,14 @@ //{{NO_DEPENDENCIES}} -// Включаемый файл, созданный в Microsoft Visual C++. -// Используется d:\Others\SVN\MirandaNG\trunk\protocols\SkypeWeb\res\resource.rc +// Microsoft Visual C++ generated include file. +// Used by W:\miranda-ng\protocols\SkypeWeb\res\resource.rc // #define IDI_SKYPE 100 #define IDC_SKYPENAME 101 #define IDC_PASSWORD 102 #define IDD_ACCOUNT_MANAGER 103 #define IDD_OPTIONS_MAIN 104 +#define IDD_MOOD 105 #define IDC_GROUP 106 -#define IDD_PASSWORD_EDITOR 107 -#define IDC_SAVEPERMANENTLY 108 #define IDD_GC_CREATE 111 #define IDD_GC_INVITE 112 #define IDI_CONFERENCE 114 @@ -26,18 +25,20 @@ #define IDC_CONTACT 1032 #define IDC_PLACE 1034 #define IDC_USEHOST 1035 -#define IDC_CHECK1 1036 #define IDC_BBCODES 1036 -#define IDC_SYSLINK1 1038 +#define IDC_MOOD_COMBO 1037 #define IDC_CHANGEPASS 1038 +#define IDC_MOOD_EMOJI 1039 +#define IDC_EDIT1 1041 +#define IDC_MOOD_TEXT 1041 // Next default values for new objects // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 124 +#define _APS_NEXT_RESOURCE_VALUE 126 #define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1039 +#define _APS_NEXT_CONTROL_VALUE 1042 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif diff --git a/protocols/SkypeWeb/src/skype_menus.cpp b/protocols/SkypeWeb/src/skype_menus.cpp index e555a1539b..5e8b35c632 100644 --- a/protocols/SkypeWeb/src/skype_menus.cpp +++ b/protocols/SkypeWeb/src/skype_menus.cpp @@ -77,6 +77,9 @@ void CSkypeProto::InitMenus() CreateServiceFunction(mi.pszService, GlobalService<&CSkypeProto::UnblockContact>); } +///////////////////////////////////////////////////////////////////////////////////////// +// Protocol's menu in the status bar + void CSkypeProto::OnBuildProtoMenu() { CMenuItem mi(&g_plugin); @@ -85,7 +88,14 @@ void CSkypeProto::OnBuildProtoMenu() mi.pszService = "/CreateNewChat"; CreateProtoService(mi.pszService, &CSkypeProto::SvcCreateChat); mi.name.a = LPGEN("Create new chat"); - mi.position = SMI_POSITION + SMI_CREATECHAT; + mi.position = 200000; mi.hIcolibItem = g_plugin.getIconHandle(IDI_CONFERENCE); Menu_AddProtoMenuItem(&mi, m_szModuleName); + + mi.pszService = "/SetMood"; + CreateProtoService(mi.pszService, &CSkypeProto::SvcSetMood); + mi.name.a = LPGEN("Set own mood"); + mi.position++; + mi.hIcolibItem = Skin_GetIconHandle(SKINICON_OTHER_USERONLINE); + Menu_AddProtoMenuItem(&mi, m_szModuleName); } diff --git a/protocols/SkypeWeb/src/skype_menus.h b/protocols/SkypeWeb/src/skype_menus.h index 2d3395dba6..748c61b773 100644 --- a/protocols/SkypeWeb/src/skype_menus.h +++ b/protocols/SkypeWeb/src/skype_menus.h @@ -27,10 +27,4 @@ enum CMI_MAX // this item shall be the last one }; -enum ProtoMenuIndexes { - SMI_CREATECHAT -}; - -#define SMI_POSITION 200000 - #endif //_SKYPE_MENUS_H_ \ No newline at end of file diff --git a/protocols/SkypeWeb/src/skype_mood.cpp b/protocols/SkypeWeb/src/skype_mood.cpp new file mode 100644 index 0000000000..386b64e7f7 --- /dev/null +++ b/protocols/SkypeWeb/src/skype_mood.cpp @@ -0,0 +1,145 @@ +/* +Copyright (C) 2012-24 Miranda NG team (https://miranda-ng.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation version 2 +of the License. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#include "stdafx.h" + +struct +{ + const char *ss; + const wchar_t *defStatus; + int defIcon; +} +static moods[] = +{ + { "", LPGENW("None") }, + { "", LPGENW("Custom emoji") }, + { "brb", LPGENW("Be right back") }, + { "burger", LPGENW("Out for lunch") }, + { "wait", LPGENW("In meetings") }, + { "learn", LPGENW("At school") }, + { "movie", LPGENW("At the movies") }, + { "plane", LPGENW("Traveling") }, + { "party", LPGENW("Celebrating") }, + { "car", LPGENW("Driving") }, + { "skip", LPGENW("At the gym") }, + { "wfh", LPGENW("Working from home") }, +}; + +struct SetStatusMsgRequest : public AsyncHttpRequest +{ + SetStatusMsgRequest(CSkypeProto *ppro) : + AsyncHttpRequest(REQUEST_POST, HOST_API, "/users/self/profile/partial") + { + int iMood = ppro->iMood; + auto &pMood = moods[iMood]; + + JSONNode node, payload; + payload.set_name("payload"); + + CMStringW s1, s2; + switch (iMood) { + case 0: // none + s1 = ppro->wstrMoodMessage; + break; + case 1: // custom + s1.Format(L"(%x) %s", Utf16toUtf32(ppro->wstrMoodEmoji), (wchar_t *)ppro->wstrMoodMessage); + break; + default: + s1.Format(L"(%S) %s", pMood.ss, (wchar_t *)ppro->wstrMoodMessage); + break; + } + payload << WCHAR_PARAM("mood", s1); + + if (iMood > 1) + s2.Format(L"(%S)%s", pMood.ss, pMood.ss, (wchar_t*)ppro->wstrMoodMessage); + else if (iMood == 1) { + int code = Utf16toUtf32(ppro->wstrMoodEmoji); + s2.Format(L"(%x)%s", code, code, (wchar_t *)ppro->wstrMoodMessage); + } + + if (!s2.IsEmpty()) + payload << WCHAR_PARAM("richMood", s2); + + node << payload; + m_szParam = node.write().c_str(); + } +}; + +int getMoodIndex(const char *pszMood) +{ + for (auto &it : moods) + if (!mir_strcmpi(it.ss, pszMood)) + return int(&it - moods); + + return -1; +} + +///////////////////////////////////////////////////////////////////////////////////////// +// Mood dialog + +class CMoodDialog : public CSkypeDlg +{ + CCtrlEdit edtText, edtEmoji; + CCtrlCombo cmbMoods; + +public: + CMoodDialog(CSkypeProto *ppro) : + CSkypeDlg(ppro, IDD_MOOD), + edtText(this, IDC_MOOD_TEXT), + edtEmoji(this, IDC_MOOD_EMOJI), + cmbMoods(this, IDC_MOOD_COMBO) + { + CreateLink(edtText, ppro->wstrMoodMessage); + CreateLink(edtEmoji, ppro->wstrMoodEmoji); + + cmbMoods.OnChange = Callback(this, &CMoodDialog::onChangeSel_Mood); + } + + bool OnInitDialog() override + { + for (auto &it : moods) + cmbMoods.AddString(TranslateW(it.defStatus), int(&it - moods)); + cmbMoods.SetCurSel(m_proto->iMood); + return true; + } + + bool OnApply() override + { + m_proto->iMood = cmbMoods.GetCurSel(); + + CMStringA szSetting(FORMAT, "Mood%d", (int)m_proto->iMood); + m_proto->setWString(szSetting, m_proto->wstrMoodMessage); + + m_proto->PushRequest(new SetStatusMsgRequest(m_proto)); + return true; + } + + void onChangeSel_Mood(CCtrlCombo *) + { + int iMood = cmbMoods.GetCurSel(); + edtEmoji.Enable(iMood == 1); + + CMStringA szSetting(FORMAT, "Mood%d", iMood); + edtText.SetText(m_proto->getMStringW(szSetting)); + } +}; + +INT_PTR CSkypeProto::SvcSetMood(WPARAM, LPARAM) +{ + CMoodDialog(this).DoModal(); + return 0; +} diff --git a/protocols/SkypeWeb/src/skype_profile.cpp b/protocols/SkypeWeb/src/skype_profile.cpp index 34c656dc14..6aba685c73 100644 --- a/protocols/SkypeWeb/src/skype_profile.cpp +++ b/protocols/SkypeWeb/src/skype_profile.cpp @@ -17,197 +17,6 @@ along with this program. If not, see . #include "stdafx.h" -std::map CSkypeProto::languages; - -void CSkypeProto::InitLanguages() -{ - std::map result; - result[L"ab"] = L"Abkhazian"; - result[L"aa"] = L"Afar"; - result[L"af"] = L"Afrikaans"; - result[L"ak"] = L"Akan"; - result[L"sq"] = L"Albanian"; - result[L"am"] = L"Amharic"; - result[L"ar"] = L"Arabic"; - result[L"an"] = L"Aragonese"; - result[L"hy"] = L"Armenian"; - result[L"as"] = L"Assamese"; - result[L"av"] = L"Avaric"; - result[L"ae"] = L"Avestan"; - result[L"ay"] = L"Aymara"; - result[L"az"] = L"Azerbaijani"; - result[L"bm"] = L"Bambara"; - result[L"ba"] = L"Bashkir"; - result[L"eu"] = L"Basque"; - result[L"be"] = L"Belarusian"; - result[L"bn"] = L"Bengali"; - result[L"bh"] = L"Bihari languages"; - result[L"bi"] = L"Bislama"; - result[L"nb"] = L"Bokmal, Norwegian"; - result[L"bs"] = L"Bosnian"; - result[L"br"] = L"Breton"; - result[L"bg"] = L"Bulgarian"; - result[L"my"] = L"Burmese"; - result[L"ca"] = L"Catalan"; - result[L"km"] = L"Central Khmer"; - result[L"ch"] = L"Chamorro"; - result[L"ce"] = L"Chechen"; - result[L"ny"] = L"Chichewa"; - result[L"zh"] = L"Chinese"; - result[L"za"] = L"Chuang"; - result[L"cu"] = L"Church Slavic"; - result[L"cv"] = L"Chuvash"; - result[L"kw"] = L"Cornish"; - result[L"co"] = L"Corsican"; - result[L"cr"] = L"Cree"; - result[L"hr"] = L"Croatian"; - result[L"cs"] = L"Czech"; - result[L"da"] = L"Danish"; - result[L"dv"] = L"Divehi"; - result[L"nl"] = L"Dutch"; - result[L"dz"] = L"Dzongkha"; - result[L"en"] = L"English"; - result[L"eo"] = L"Esperanto"; - result[L"et"] = L"Estonian"; - result[L"ee"] = L"Ewe"; - result[L"fo"] = L"Faroese"; - result[L"fj"] = L"Fijian"; - result[L"fi"] = L"Finnish"; - result[L"fr"] = L"French"; - result[L"ff"] = L"Fulah"; - result[L"gd"] = L"Gaelic"; - result[L"gl"] = L"Galician"; - result[L"lg"] = L"Ganda"; - result[L"ka"] = L"Georgian"; - result[L"de"] = L"German"; - result[L"ki"] = L"Gikuyu"; - result[L"el"] = L"Greek, Modern (1453-)"; - result[L"kl"] = L"Greenlandic"; - result[L"gn"] = L"Guarani"; - result[L"gu"] = L"Gujarati"; - result[L"ht"] = L"Haitian Creole"; - result[L"ha"] = L"Hausa"; - result[L"he"] = L"Hebrew"; - result[L"hz"] = L"Herero"; - result[L"hi"] = L"Hindi"; - result[L"ho"] = L"Hiri Motu"; - result[L"hu"] = L"Hungarian"; - result[L"is"] = L"Icelandic"; - result[L"io"] = L"Ido"; - result[L"ig"] = L"Igbo"; - result[L"id"] = L"Indonesian"; - result[L"ia"] = L"Interlingua (International Auxiliary Language Association)"; - result[L"ie"] = L"Interlingue"; - result[L"iu"] = L"Inuktitut"; - result[L"ik"] = L"Inupiaq"; - result[L"ga"] = L"Irish"; - result[L"it"] = L"Italian"; - result[L"ja"] = L"Japanese"; - result[L"jv"] = L"Javanese"; - result[L"kn"] = L"Kannada"; - result[L"kr"] = L"Kanuri"; - result[L"ks"] = L"Kashmiri"; - result[L"kk"] = L"Kazakh"; - result[L"rw"] = L"Kinyarwanda"; - result[L"ky"] = L"Kirghiz"; - result[L"kv"] = L"Komi"; - result[L"kg"] = L"Kongo"; - result[L"ko"] = L"Korean"; - result[L"kj"] = L"Kuanyama"; - result[L"ku"] = L"Kurdish"; - result[L"lo"] = L"Lao"; - result[L"la"] = L"Latin"; - result[L"lv"] = L"Latvian"; - result[L"lb"] = L"Letzeburgesch"; - result[L"this"] = L"Limburgan"; - result[L"ln"] = L"Lingala"; - result[L"lt"] = L"Lithuanian"; - result[L"lu"] = L"Luba-Katanga"; - result[L"mk"] = L"Macedonian"; - result[L"mg"] = L"Malagasy"; - result[L"ms"] = L"Malay"; - result[L"ml"] = L"Malayalam"; - result[L"mt"] = L"Maltese"; - result[L"gv"] = L"Manx"; - result[L"mi"] = L"Maori"; - result[L"mr"] = L"Marathi"; - result[L"mh"] = L"Marshallese"; - result[L"mn"] = L"Mongolian"; - result[L"na"] = L"Nauru"; - result[L"nv"] = L"Navajo"; - result[L"nd"] = L"Ndebele, North"; - result[L"nr"] = L"Ndebele, South"; - result[L"ng"] = L"Ndonga"; - result[L"ne"] = L"Nepali"; - result[L"se"] = L"Northern Sami"; - result[L"no"] = L"Norwegian"; - result[L"nn"] = L"Norwegian Nynorsk"; - result[L"ii"] = L"Nuosu"; - result[L"oc"] = L"Occitan (post 1500)"; - result[L"oj"] = L"Ojibwa"; - result[L"or"] = L"Oriya"; - result[L"om"] = L"Oromo"; - result[L"os"] = L"Ossetic"; - result[L"pi"] = L"Pali"; - result[L"pa"] = L"Panjabi"; - result[L"ps"] = L"Pashto"; - result[L"fa"] = L"Persian"; - result[L"pl"] = L"Polish"; - result[L"pt"] = L"Portuguese"; - result[L"qu"] = L"Quechua"; - result[L"ro"] = L"Romanian"; - result[L"rm"] = L"Romansh"; - result[L"rn"] = L"Rundi"; - result[L"ru"] = L"Russian"; - result[L"sm"] = L"Samoan"; - result[L"sg"] = L"Sango"; - result[L"sa"] = L"Sanskrit"; - result[L"sc"] = L"Sardinian"; - result[L"sr"] = L"Serbian"; - result[L"sn"] = L"Shona"; - result[L"sd"] = L"Sindhi"; - result[L"si"] = L"Sinhalese"; - result[L"sk"] = L"Slovak"; - result[L"sl"] = L"Slovenian"; - result[L"so"] = L"Somali"; - result[L"st"] = L"Sotho, Southern"; - result[L"es"] = L"Spanish"; - result[L"su"] = L"Sundanese"; - result[L"sw"] = L"Swahili"; - result[L"ss"] = L"Swati"; - result[L"sv"] = L"Swedish"; - result[L"tl"] = L"Tagalog"; - result[L"ty"] = L"Tahitian"; - result[L"tg"] = L"Tajik"; - result[L"ta"] = L"Tamil"; - result[L"tt"] = L"Tatar"; - result[L"te"] = L"Telugu"; - result[L"th"] = L"Thai"; - result[L"bo"] = L"Tibetan"; - result[L"ti"] = L"Tigrinya"; - result[L"to"] = L"Tonga (Tonga Islands)"; - result[L"ts"] = L"Tsonga"; - result[L"tn"] = L"Tswana"; - result[L"tr"] = L"Turkish"; - result[L"tk"] = L"Turkmen"; - result[L"tw"] = L"Twi"; - result[L"ug"] = L"Uighur"; - result[L"uk"] = L"Ukrainian"; - result[L"ur"] = L"Urdu"; - result[L"uz"] = L"Uzbek"; - result[L"ve"] = L"Venda"; - result[L"vi"] = L"Vietnamese"; - result[L"vo"] = L"Volapuk"; - result[L"wa"] = L"Walloon"; - result[L"cy"] = L"Welsh"; - result[L"fy"] = L"Western Frisian"; - result[L"wo"] = L"Wolof"; - result[L"xh"] = L"Xhosa"; - result[L"yi"] = L"Yiddish"; - result[L"yo"] = L"Yoruba"; - result[L"zu"] = L"Zulu"; -} - void CSkypeProto::UpdateProfileDisplayName(const JSONNode &root, MCONTACT hContact) { ptrW firstname(getWStringA(hContact, "FirstName")); @@ -262,15 +71,6 @@ void CSkypeProto::UpdateProfileCountry(const JSONNode &root, MCONTACT hContact) else delSetting(hContact, "Country"); } -void CSkypeProto::UpdateProfileLanguage(const JSONNode &root, MCONTACT hContact) -{ - CMStringW isocode = root["language"].as_mstring(); - if (!isocode.IsEmpty() && isocode != "null") - setWString(hContact, "Language0", languages[isocode.GetBuffer()].c_str()); - else - delSetting(hContact, "Language0"); -} - void CSkypeProto::UpdateProfileEmails(const JSONNode &root, MCONTACT hContact) { const JSONNode &node = root["emails"]; @@ -332,14 +132,15 @@ void CSkypeProto::LoadProfile(MHttpResponse *response, AsyncHttpRequest *pReques SetString(hContact, "Homepage", root["homepage"]); SetString(hContact, "LastName", root["lastname"]); SetString(hContact, "FirstName", root["firstname"]); - SetString(hContact, "XStatusMsg", root["richMood"]); SetString(hContact, "CompanyPhone", root["phoneOffice"]); + if (auto &pMood = root["richMood"]) + RemoveHtml(pMood.as_mstring(), true); // this call extracts only emoji / mood id + UpdateProfileDisplayName(root, hContact); UpdateProfileGender(root, hContact); UpdateProfileBirthday(root, hContact); UpdateProfileCountry(root, hContact); - UpdateProfileLanguage(root, hContact); UpdateProfileEmails(root, hContact); UpdateProfileAvatar(root, hContact); diff --git a/protocols/SkypeWeb/src/skype_proto.cpp b/protocols/SkypeWeb/src/skype_proto.cpp index 03315502a4..148be02f4e 100644 --- a/protocols/SkypeWeb/src/skype_proto.cpp +++ b/protocols/SkypeWeb/src/skype_proto.cpp @@ -17,7 +17,7 @@ along with this program. If not, see . #include "stdafx.h" -CSkypeProto::CSkypeProto(const char* protoName, const wchar_t* userName) : +CSkypeProto::CSkypeProto(const char *protoName, const wchar_t *userName) : PROTO(protoName, userName), m_PopupClasses(1), m_OutMessages(3, PtrKeySortT), @@ -28,7 +28,10 @@ CSkypeProto::CSkypeProto(const char* protoName, const wchar_t* userName) : bUseBBCodes(this, "UseBBCodes", true), bUseServerTime(this, "UseServerTime", false), wstrCListGroup(this, SKYPE_SETTINGS_GROUP, L"Skype"), - wstrPlace(this, "Place", L"") + wstrPlace(this, "Place", L""), + iMood(this, "Mood", 0), + wstrMoodEmoji(this, "MoodEmoji", L""), + wstrMoodMessage(this, "XStatusMsg", L"") { NETLIBUSER nlu = {}; nlu.flags = NUF_OUTGOING | NUF_INCOMING | NUF_HTTPCONNS | NUF_UNICODE; @@ -98,39 +101,8 @@ INT_PTR CSkypeProto::GetCaps(int type, MCONTACT) return 0; } -int CSkypeProto::SetAwayMsg(int, const wchar_t *msg) -{ - if (IsOnline()) - PushRequest(new SetStatusMsgRequest(msg ? T2Utf(msg) : "")); - return 0; -} - ///////////////////////////////////////////////////////////////////////////////////////// -void CSkypeProto::OnReceiveAwayMsg(MHttpResponse *response, AsyncHttpRequest *pRequest) -{ - JsonReply reply(response); - if (reply.error()) - return; - - MCONTACT hContact = DWORD_PTR(pRequest->pUserInfo); - auto &root = reply.data(); - if (JSONNode &mood = root["mood"]) { - CMStringW str = mood.as_mstring(); - ProtoBroadcastAck(hContact, ACKTYPE_AWAYMSG, ACKRESULT_SUCCESS, (HANDLE)1, (LPARAM)str.c_str()); - } - else { - ProtoBroadcastAck(hContact, ACKTYPE_AWAYMSG, ACKRESULT_SUCCESS, (HANDLE)1, 0); - } -} - -HANDLE CSkypeProto::GetAwayMsg(MCONTACT hContact) -{ - auto *pReq = new GetProfileRequest(this, hContact); - pReq->m_pFunc = &CSkypeProto::OnReceiveAwayMsg; - return (HANDLE)1; -} - MCONTACT CSkypeProto::AddToList(int, PROTOSEARCHRESULT *psr) { debugLogA(__FUNCTION__); diff --git a/protocols/SkypeWeb/src/skype_proto.h b/protocols/SkypeWeb/src/skype_proto.h index ebddc9ba3d..6f13fa6da6 100644 --- a/protocols/SkypeWeb/src/skype_proto.h +++ b/protocols/SkypeWeb/src/skype_proto.h @@ -29,6 +29,7 @@ struct CSkypeProto : public PROTO friend class CSkypeOptionsMain; friend class CSkypeGCCreateDlg; friend class CSkypeInviteDlg; + friend class CMoodDialog; class CSkypeProtoImpl { @@ -70,8 +71,6 @@ public: int UserIsTyping(MCONTACT hContact, int type) override; int RecvContacts(MCONTACT hContact, DB::EventInfo &dbei) override; HANDLE SendFile(MCONTACT hContact, const wchar_t *szDescription, wchar_t **ppszFiles) override; - HANDLE GetAwayMsg(MCONTACT hContact) override; - int SetAwayMsg(int m_iStatus, const wchar_t *msg) override; void OnBuildProtoMenu(void) override; bool OnContactDeleted(MCONTACT, uint32_t flags) override; @@ -91,12 +90,12 @@ public: void InitPopups(); void UninitPopups(); - // languages - static void InitLanguages(); - // search void __cdecl SearchBasicThread(void *param); + // threads + void __cdecl CSkypeProto::SendFileThread(void *p); + ////////////////////////////////////////////////////////////////////////////////////// // services @@ -115,6 +114,9 @@ public: CMOption wstrCListGroup; + CMOption iMood; + CMOption wstrMoodMessage, wstrMoodEmoji; + ////////////////////////////////////////////////////////////////////////////////////// // other data @@ -155,7 +157,6 @@ public: void OnUnblockContact(MHttpResponse *response, AsyncHttpRequest *pRequest); void OnMessageSent(MHttpResponse *response, AsyncHttpRequest *pRequest); - void OnReceiveAwayMsg(MHttpResponse *response, AsyncHttpRequest *pRequest); void OnGetServerHistory(MHttpResponse *response, AsyncHttpRequest *pRequest); void OnSyncConversations(MHttpResponse *response, AsyncHttpRequest *pRequest); @@ -227,12 +228,9 @@ private: void UpdateProfileGender(const JSONNode &root, MCONTACT hContact = NULL); void UpdateProfileBirthday(const JSONNode &root, MCONTACT hContact = NULL); void UpdateProfileCountry(const JSONNode &node, MCONTACT hContact = NULL); - void UpdateProfileLanguage(const JSONNode &root, MCONTACT hContact = NULL); void UpdateProfileEmails(const JSONNode &root, MCONTACT hContact = NULL); void UpdateProfileAvatar(const JSONNode &root, MCONTACT hContact = NULL); - void __cdecl CSkypeProto::SendFileThread(void *p); - // contacts uint16_t GetContactStatus(MCONTACT hContact); void SetContactStatus(MCONTACT hContact, uint16_t status); @@ -310,6 +308,8 @@ private: int64_t getLastTime(MCONTACT); void setLastTime(MCONTACT, int64_t); + CMStringW RemoveHtml(const CMStringW &src, bool bCheckSS = false); + static time_t IsoToUnixTime(const std::string &stamp); static int SkypeToMirandaStatus(const char *status); @@ -333,11 +333,12 @@ private: // services INT_PTR __cdecl BlockContact(WPARAM hContact, LPARAM); INT_PTR __cdecl UnblockContact(WPARAM hContact, LPARAM); - INT_PTR __cdecl OnRequestAuth(WPARAM hContact, LPARAM lParam); + INT_PTR __cdecl OnRequestAuth(WPARAM hContact, LPARAM); INT_PTR __cdecl OnGrantAuth(WPARAM hContact, LPARAM); - INT_PTR __cdecl SvcLoadHistory(WPARAM hContact, LPARAM lParam); - INT_PTR __cdecl SvcEmptyHistory(WPARAM hContact, LPARAM lParam); + INT_PTR __cdecl SvcLoadHistory(WPARAM hContact, LPARAM); + INT_PTR __cdecl SvcEmptyHistory(WPARAM hContact, LPARAM); INT_PTR __cdecl SvcCreateChat(WPARAM, LPARAM); + INT_PTR __cdecl SvcSetMood(WPARAM, LPARAM); INT_PTR __cdecl ParseSkypeUriService(WPARAM, LPARAM lParam); template diff --git a/protocols/SkypeWeb/src/skype_utils.cpp b/protocols/SkypeWeb/src/skype_utils.cpp index 2de2bc25d8..e8986e5b08 100644 --- a/protocols/SkypeWeb/src/skype_utils.cpp +++ b/protocols/SkypeWeb/src/skype_utils.cpp @@ -344,18 +344,7 @@ const HtmlEntity htmlEntities[] = { "zwnj", "\xE2\x80\x8C" } }; -static void Utf32toUtf16(uint32_t c, CMStringW &dest) -{ - if (c < 0x10000) - dest.AppendChar(c); - else { - unsigned int t = c - 0x10000; - dest.AppendChar((((t << 12) >> 22) + 0xD800)); - dest.AppendChar((((t << 22) >> 22) + 0xDC00)); - } -} - -CMStringW RemoveHtml(const CMStringW &data) +CMStringW CSkypeProto::RemoveHtml(const CMStringW &data, bool bCheckSS) { bool inSS = false; CMStringW new_string; @@ -363,10 +352,14 @@ CMStringW RemoveHtml(const CMStringW &data) for (int i = 0; i < data.GetLength(); i++) { wchar_t c = data[i]; if (c == '<') { - if (!wcsncmp(data.c_str() + i + 1, L"ss ", 3)) + if (bCheckSS && !wcsncmp(data.c_str() + i + 1, L"ss ", 3)) inSS = true; - else if (!wcsncmp(data.c_str() + i + 1, L"/ss>", 4)) + else if (!wcsncmp(data.c_str() + i + 1, L"/ss>", 4)) { + CMStringW wszStatusMsg = data.Mid(i + 5); + wszStatusMsg.Trim(); + wstrMoodMessage = wszStatusMsg; inSS = false; + } i = data.Find('>', i); if (i == -1) @@ -441,12 +434,17 @@ CMStringW RemoveHtml(const CMStringW &data) } if (c == '(' && inSS) { - uint32_t code = 0; - if (1 == swscanf(data.c_str() + i + 1, L"%x_", &code)) - Utf32toUtf16(code, new_string); - int iEnd = data.Find(')', i); if (iEnd != -1) { + CMStringW ss(data.Mid(i + 1, iEnd - i - 1)); + uint32_t code = getMoodIndex(T2Utf(ss)); + if (code != -1) + iMood = code; + else if (1 == swscanf(ss, L"%x_", &code)) { + Utf32toUtf16(code, new_string); + wstrMoodEmoji = new_string; + } + i = iEnd; continue; } @@ -460,6 +458,34 @@ CMStringW RemoveHtml(const CMStringW &data) ////////////////////////////////////////////////////////////////////////////////////////// +void Utf32toUtf16(uint32_t c, CMStringW &dest) +{ + if (c < 0x10000) + dest.AppendChar(c); + else { + unsigned int t = c - 0x10000; + dest.AppendChar((((t << 12) >> 22) + 0xD800)); + dest.AppendChar((((t << 22) >> 22) + 0xDC00)); + } +} + +bool is_surrogate(wchar_t uc) { return (uc - 0xd800u) < 2048u; } +bool is_high_surrogate(wchar_t uc) { return (uc & 0xfffffc00) == 0xd800; } +bool is_low_surrogate(wchar_t uc) { return (uc & 0xfffffc00) == 0xdc00; } + +uint32_t Utf16toUtf32(const wchar_t *str) +{ + if (!is_surrogate(str[0])) + return str[0]; + + if (is_high_surrogate(str[0]) && is_low_surrogate(str[1])) + return (str[0] << 10) + str[1] - 0x35fdc00; + + return 0; +} + +////////////////////////////////////////////////////////////////////////////////////////// + const char* CSkypeProto::MirandaToSkypeStatus(int status) { switch (status) { diff --git a/protocols/SkypeWeb/src/skype_utils.h b/protocols/SkypeWeb/src/skype_utils.h index 2835ae45da..4a7f28e4c4 100644 --- a/protocols/SkypeWeb/src/skype_utils.h +++ b/protocols/SkypeWeb/src/skype_utils.h @@ -18,7 +18,8 @@ along with this program. If not, see . #ifndef _UTILS_H_ #define _UTILS_H_ -CMStringW RemoveHtml(const CMStringW &src); +void Utf32toUtf16(uint32_t c, CMStringW &dest); +uint32_t Utf16toUtf32(const wchar_t *str); const char* GetSkypeNick(const char *pszSkypeId); const wchar_t* GetSkypeNick(const wchar_t *szSkypeId); @@ -30,6 +31,8 @@ bool IsPossibleUserType(const char *pszUserId); CMStringA UrlToSkypeId(const char *url, int *pUserType = nullptr); CMStringW UrlToSkypeId(const wchar_t *url, int *pUserType = nullptr); +int getMoodIndex(const char *pszMood); + class EventHandle { HANDLE _hEvent; diff --git a/protocols/SkypeWeb/src/stdafx.h b/protocols/SkypeWeb/src/stdafx.h index 35f3a49207..579cf506f4 100644 --- a/protocols/SkypeWeb/src/stdafx.h +++ b/protocols/SkypeWeb/src/stdafx.h @@ -57,6 +57,7 @@ along with this program. If not, see . #include struct CSkypeProto; +typedef CProtoDlgBase CSkypeDlg; extern char g_szMirVer[]; extern HANDLE g_hCallEvent; -- cgit v1.2.3