You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1069 lines
34 KiB
Plaintext
1069 lines
34 KiB
Plaintext
unit viewinfoDlg;
|
|
{$I RnQConfig.inc}
|
|
|
|
interface
|
|
|
|
uses
|
|
Winapi.Windows, System.UITypes, System.SysUtils, System.Classes, System.DateUtils, System.AnsiStrings, System.Variants,
|
|
Generics.Defaults, Generics.Collections,
|
|
RDGlobal, RDUtils, RQUtil, RnQ_Avatars, RnQStrings, RnQDialogs, RnQLangs, RnQSysUtils, RnQGraphics32, RnQNet,
|
|
ICQCommon, ICQContacts, ICQConsts, ICQSession, Protocol_ICQ, Protocols_all, globalLib, utilLib,
|
|
SciterJS, SciterJSAPI, SciterLib;
|
|
|
|
{$I PubRTTI.inc}
|
|
|
|
type
|
|
TViewInfo = record
|
|
itsMe: Boolean;
|
|
//genders, langs, gmts, maritals, birthday, countries{, interest}: TParams;
|
|
end;
|
|
|
|
TViewInfoContactData = record
|
|
m_uin, m_display, m_nick, m_firstname, m_lastname, m_about, m_status,
|
|
p_cellular, p_home, p_other, p_sms, p_work,
|
|
e_lastmsgtime, e_lastonlinetime, e_onlinesince, e_regon, e_infoupd, e_lastinfoupd, e_group, e_uinlists,
|
|
c_attachedmail, c_client, caps_desc, caps_hex,
|
|
ns_important, ns_nickname, ns_sms, ns_cell1, ns_cell2, ns_cell3, nl_important, nl_notes: String;
|
|
m_birthl: Variant;
|
|
a_showtype: Integer;
|
|
m_smsable, e_nodbdelete, c_translit: Boolean;
|
|
end;
|
|
|
|
TViewInfoData = record
|
|
caption, statusImg, xstatus, xstatustext: String;
|
|
userType: Integer;
|
|
values: Variant;
|
|
end;
|
|
|
|
{$I NoRTTI.inc}
|
|
|
|
TViewInfoMethods = class(TNativeMethods)
|
|
class procedure RegisterMethods(var ReturnValue: TSciterValue); override;
|
|
class procedure GetContactViewInfo(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
class procedure GetContactViewInfoData(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
class procedure GetContactInfo(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
class procedure DeleteContactFromList(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
class procedure SaveServerInfo(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
class procedure SaveLocalInfo(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
class procedure IsContactInCL(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
class procedure UpdateBirthAge(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
class procedure SetIconShowType(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
class procedure SetNoDBDelete(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
class procedure SetTranslit(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
class procedure ApplyInfoStatus(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
class procedure ApplyNotes(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
class procedure VerifyPhone(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
class procedure LoadAvatarAsync(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
class procedure LoadThumb(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
class procedure LoadPhoto(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
class procedure ClearAvatarOrPhoto(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
class procedure ChangeAvatar(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
class procedure GetCaptionColors(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
end;
|
|
|
|
procedure UpdateViewInfo(Contact: TICQContact);
|
|
procedure OpenViewInfo(Contact: TICQContact);
|
|
|
|
type
|
|
TCap = record
|
|
HEX: String;
|
|
Desc: String;
|
|
end;
|
|
{
|
|
tagCOLORIZATIONPARAMS = record
|
|
clrColor : COLORREF;
|
|
clrAftGlow : COLORREF;
|
|
nIntensity : UINT;
|
|
clrAftGlowBal : UINT;
|
|
clrBlurBal : UINT;
|
|
clrGlassReflInt : UINT;
|
|
fOpaque : BOOL;
|
|
end;
|
|
|
|
COLORIZATIONPARAMS = tagCOLORIZATIONPARAMS;
|
|
TColorizationParams = COLORIZATIONPARAMS;
|
|
PColorizationParams = ^TColorizationParams;
|
|
}
|
|
var
|
|
FWndFrameSize: Integer;
|
|
// borderInactiveClr: String;
|
|
|
|
// procedure DwmGetColorizationParameters(out parameters: TColorizationParams); stdcall; external 'dwmapi.dll' index 127;
|
|
|
|
implementation
|
|
|
|
uses
|
|
RoasterLib;
|
|
|
|
function IsUpToDate(Contact: TICQContact): Boolean;
|
|
|
|
function Newer(Date: TDateTime): Boolean;
|
|
begin
|
|
Result := (Date > 10000) and (Date < Now) and (Date > Contact.InfoUpdatedTo)
|
|
end;
|
|
|
|
begin
|
|
with Contact do
|
|
Result := not (Newer(LastCapsUpdate) or Newer(LastInfoUpdate) or Newer(LastStatusUpdate))
|
|
end;
|
|
|
|
function GenerateCaption(Contact: TICQContact): String;
|
|
begin
|
|
with Contact do
|
|
begin
|
|
Result := Contact.Displayed;
|
|
if NoDB then
|
|
Result := Result + ' ' + GetTranslation('- user not found on server')
|
|
else if InfoUpdatedTo = 0 then
|
|
Result := Result + ' ' + GetTranslation('- no info')
|
|
else if not IsUpToDate(Contact) then
|
|
Result := Result + ' ' + GetTranslation('- newer info available on server');
|
|
end;
|
|
end;
|
|
|
|
procedure UpdateViewInfo(Contact: TICQContact);
|
|
begin
|
|
UI.ViewInfo(Contact.UID, GenerateCaption(Contact), True);
|
|
end;
|
|
|
|
procedure OpenViewInfo(Contact: TICQContact);
|
|
begin
|
|
UI.ViewInfo(Contact.UID, GenerateCaption(Contact), False);
|
|
end;
|
|
{
|
|
function DWM_ExtendFrameIntoClientArea(hwnd: HWND; ATopHeight, ALeftWidth, ABottomHeight, ARightWidth: Integer): HRESULT;
|
|
var
|
|
lMargins: TMargins;
|
|
begin
|
|
lMargins.cyTopHeight := ATopHeight;
|
|
lMargins.cyBottomHeight := ABottomHeight;
|
|
lMargins.cxLeftWidth := ALeftWidth;
|
|
lMargins.cxRightWidth := ARightWidth;
|
|
Result := DwmExtendFrameIntoClientArea(hwnd, lMargins);
|
|
end;
|
|
|
|
procedure DWM_GetBorderColor;
|
|
var
|
|
Params: TColorizationParams;
|
|
begin
|
|
ZeroMemory(@Params, SizeOf(Params));
|
|
DwmGetColorizationParameters(Params);
|
|
borderActiveClr := '#' + RGB(GetRValue(Params.clrColor), GetGValue(Params.clrColor), GetBValue(Params.clrColor)).ToHexString;
|
|
end;
|
|
}
|
|
function GetArgumentContact(argv: PSciterValue): TICQContact;
|
|
var
|
|
UIN: PWideChar;
|
|
StrLen: Cardinal;
|
|
begin
|
|
Result := nil;
|
|
UIN := '';
|
|
API.ValueStringData(argv, UIN, StrLen);
|
|
|
|
if not (UIN = '') then
|
|
Result := Account.AccProto.GetContact(UIN);
|
|
end;
|
|
|
|
class procedure TViewInfoMethods.RegisterMethods(var ReturnValue: TSciterValue);
|
|
begin
|
|
AddMethod('GetContactViewInfo', GetContactViewInfo);
|
|
AddMethod('GetContactViewInfoData', GetContactViewInfoData);
|
|
AddMethod('GetContactInfo', GetContactInfo);
|
|
AddMethod('DeleteContactFromList', DeleteContactFromList);
|
|
AddMethod('SaveServerInfo', SaveServerInfo);
|
|
AddMethod('SaveLocalInfo', SaveLocalInfo);
|
|
AddMethod('IsContactInCL', IsContactInCL);
|
|
AddMethod('UpdateBirthAge', UpdateBirthAge);
|
|
AddMethod('SetIconShowType', SetIconShowType);
|
|
AddMethod('SetNoDBDelete', SetNoDBDelete);
|
|
AddMethod('SetTranslit', SetTranslit);
|
|
AddMethod('ApplyInfoStatus', ApplyInfoStatus);
|
|
AddMethod('ApplyNotes', ApplyNotes);
|
|
AddMethod('VerifyPhone', VerifyPhone);
|
|
AddMethod('LoadAvatarAsync', LoadAvatarAsync);
|
|
AddMethod('LoadThumb', LoadThumb);
|
|
AddMethod('LoadPhoto', LoadPhoto);
|
|
AddMethod('ClearAvatarOrPhoto', ClearAvatarOrPhoto);
|
|
AddMethod('ChangeAvatar', ChangeAvatar);
|
|
AddMethod('GetCaptionColors', GetCaptionColors);
|
|
inherited;
|
|
end;
|
|
|
|
class procedure TViewInfoMethods.GetContactViewInfo(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
var
|
|
Contact: TICQContact;
|
|
Info: TViewInfo;
|
|
|
|
//i: Integer;
|
|
//cntry: TPair |
|
//comp: TComponent;
|
|
ItsMe: Boolean;
|
|
begin
|
|
Contact := GetArgumentContact(argv);
|
|
if not Assigned(Contact) then
|
|
Exit;
|
|
|
|
ItsMe := Account.AccProto.IsMyAcc(Contact);
|
|
// readOnlyContact := not ItsMe;
|
|
Info.itsMe := ItsMe;
|
|
|
|
// SetLength(Info.genders, Length(Genders) + 1);
|
|
// Info.genders[0] := VarArrayCreate([0, 1], varVariant);
|
|
// Info.genders[0][0] := 0;
|
|
// Info.genders[0][1] := GetTranslation('Not selected');
|
|
// for i := Low(Genders) to High(Genders) do
|
|
// begin
|
|
// Info.genders[i + 1] := VarArrayCreate([0, 1], varVariant);
|
|
// Info.genders[i + 1][0] := Genders[i].ID;
|
|
// Info.genders[i + 1][1] := GetTranslation(Genders[i].Value);
|
|
// end;
|
|
//
|
|
// SetLength(Info.maritals, Length(MarSts));
|
|
// for i := Low(MarSts) to High(MarSts) do
|
|
// begin
|
|
// Info.maritals[i] := VarArrayCreate([0, 1], varVariant);
|
|
// Info.maritals[i][0] := MarSts[i].ID;
|
|
// Info.maritals[i][1] := GetTranslation(MarSts[i].Value);
|
|
// end;
|
|
//
|
|
// SetLength(Info.birthday, 2);
|
|
// Info.birthday[0] := VarArrayCreate([0, 1], varVariant);
|
|
// Info.birthday[0][0] := 0;
|
|
// Info.birthday[0][1] := GetTranslation('Not specified');
|
|
// Info.birthday[1] := VarArrayCreate([0, 1], varVariant);
|
|
// Info.birthday[1][0] := 1;
|
|
// Info.birthday[1][1] := GetTranslation('Birthday');
|
|
//
|
|
// SetLength(Info.langs, Length(Languages) + 1);
|
|
// Info.langs[0] := VarArrayCreate([0, 1], varVariant);
|
|
// Info.langs[0][0] := '';
|
|
// Info.langs[0][1] := GetTranslation('Not selected');
|
|
// for i := Low(Languages) to High(Languages) do
|
|
// begin
|
|
// Info.langs[i + 1] := VarArrayCreate([0, 1], varVariant);
|
|
// Info.langs[i + 1][0] := Languages[i].ID;
|
|
// Info.langs[i + 1][1] := GetTranslation(Languages[i].Value);
|
|
// end;
|
|
//
|
|
// SetLength(Info.gmts, Length(GMTs));
|
|
// for i := Low(GMTs) to High(GMTs) do
|
|
// begin
|
|
// Info.gmts[i] := VarArrayCreate([0, 1], varVariant);
|
|
// Info.gmts[i][0] := GMTs[i].ID;
|
|
// Info.gmts[i][1] := GetTranslation(GMTs[i].Value);
|
|
// end;
|
|
//
|
|
// SetLength(Info.countries, ISOCountries.Count + 1);
|
|
// Info.countries[0] := VarArrayCreate([0, 1], varVariant);
|
|
// Info.countries[0][0] := '';
|
|
// Info.countries[0][1] := '';
|
|
|
|
// i := 1;
|
|
// for cntry in ISOCountries do
|
|
// begin
|
|
//// if Countries[i].ID = 9999 then
|
|
//// begin
|
|
//// country[1] := VarArrayCreate([0, 1], varVariant);
|
|
//// country[1][0] := Countries[i].ID;
|
|
//// country[1][1] := GetTranslation(Countries[i].Value);
|
|
//// end
|
|
//// else
|
|
//// begin
|
|
// Info.countries[i] := VarArrayCreate([0, 1], varVariant);
|
|
// Info.countries[i][0] := cntry.Key;
|
|
// Info.countries[i][1] := GetTranslation(cntry.Value);
|
|
// Inc(i);
|
|
//// end;
|
|
// end;
|
|
{
|
|
SetLength(interest, Length(arrInterests) + 1);
|
|
interest[0] := VarArrayCreate([0, 1], varVariant);
|
|
interest[0][0] := 0;
|
|
interest[0][1] := '';
|
|
for i := Low(arrInterests) to High(arrInterests) do
|
|
begin
|
|
interest[i + 1] := VarArrayCreate([0, 1], varVariant);
|
|
interest[i + 1][0] := arrInterests[i].ID;
|
|
interest[i + 1][1] := GetTranslation(arrInterests[i].Value);
|
|
end;
|
|
}
|
|
// if contact.InfoUpdatedTo = 0 then
|
|
// Account.AccProto.GetProfile(contact.UID2cmp);
|
|
|
|
V2S(UI.RecordToVar(Info), retval);
|
|
end;
|
|
|
|
class procedure TViewInfoMethods.GetContactInfo(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
var
|
|
Contact: TICQContact;
|
|
begin
|
|
if OnlFeature(Account.AccProto) then
|
|
begin
|
|
Contact := GetArgumentContact(argv);
|
|
if Assigned(Contact) then
|
|
begin
|
|
Account.AccProto.GetProfile(Contact.UID);
|
|
Account.AccProto.GetLastSeen([Contact.UID]);
|
|
// Partial data in one packet
|
|
//TICQSession(contact.fProto).sendAdvQueryInfo(contact.uid2Cmp, contact.InfoToken);
|
|
// Produces a lot of incoming packets with data
|
|
//TICQSession(contact.fProto).sendFullQueryInfo(contact.UID2cmp);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
class procedure TViewInfoMethods.DeleteContactFromList(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
var
|
|
Contact: TICQContact;
|
|
begin
|
|
Contact := GetArgumentContact(argv);
|
|
if not Assigned(Contact) then
|
|
Exit;
|
|
// if not roasterLib.exists(contact) then
|
|
if not Contact.IsInRoster then
|
|
MsgDlg('This contact is not in your list', True, mtWarning)
|
|
else if MessageDlg(GetTranslation('Are you sure you want to delete %s from your list?', [Contact.Displayed]), mtConfirmation, [mbYes, mbNo]) = mrYes then
|
|
roasterLib.Remove(Contact);
|
|
end;
|
|
|
|
class procedure TViewInfoMethods.IsContactInCL(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
var
|
|
Contact: TICQContact;
|
|
begin
|
|
Contact := GetArgumentContact(argv);
|
|
if not Assigned(Contact) then
|
|
Exit;
|
|
V2S(Assigned(Contact) and Contact.IsInRoster, retval);
|
|
end;
|
|
|
|
class procedure TViewInfoMethods.SaveServerInfo(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
var
|
|
Contact: TICQContact;
|
|
strData: PWideChar;
|
|
strLen: UINT;
|
|
pair: TSciterValue;
|
|
i, cnt, sz: Cardinal;
|
|
Birthday, BirthLChk: Boolean;
|
|
tmpVal: TSciterValue;
|
|
|
|
function GetString: PWideChar;
|
|
begin
|
|
Result := '';
|
|
API.ValueStringData(@tmpVal, Result, strLen);
|
|
end;
|
|
|
|
function GetInt: Integer;
|
|
begin
|
|
Result := 0;
|
|
API.ValueIntData(@tmpVal, Result);
|
|
end;
|
|
|
|
function GetFloat: Double;
|
|
begin
|
|
Result := 0;
|
|
API.ValueFloatData(@tmpVal, Result);
|
|
end;
|
|
|
|
function GetDate: TDateTime;
|
|
var
|
|
dRes: Double;
|
|
begin
|
|
API.ValueFloatData(@tmpVal, dRes);
|
|
Result := Trunc(UnixToDateTime(Trunc(dRes), False));
|
|
end;
|
|
|
|
function GetBool: LongBool;
|
|
var
|
|
tmpInt: Integer;
|
|
begin
|
|
API.ValueIntData(@tmpVal, tmpInt);
|
|
Result := tmpInt = 1;
|
|
end;
|
|
|
|
begin
|
|
if argc < 2 then
|
|
Exit;
|
|
|
|
Contact := GetArgumentContact(argv);
|
|
if not Assigned(Contact) or not OnlFeature(Account.AccProto) then
|
|
Exit;
|
|
|
|
Contact.age := 0;
|
|
Contact.birth := 0;
|
|
BirthLChk := False;
|
|
Birthday := False;
|
|
|
|
{
|
|
for i := Low(Contact.interests.InterestBlock) to High(Contact.interests.InterestBlock) do
|
|
if not Assigned(Contact.interests.InterestBlock[i].Names) then
|
|
Contact.interests.InterestBlock[i].Names := TStringList.create
|
|
else
|
|
Contact.interests.InterestBlock[i].Names.Clear;
|
|
Contact.interests.count := 0;
|
|
}
|
|
Inc(argv);
|
|
API.ValueIsolate(argv);
|
|
API.ValueElementsCount(argv, cnt);
|
|
for i := 0 to cnt - 1 do
|
|
begin
|
|
API.ValueNthElementValue(argv, i, pair);
|
|
API.ValueElementsCount(@pair, sz);
|
|
if sz < 2 then Continue;
|
|
strData := '';
|
|
API.ValueNthElementValue(@pair, 0, tmpVal);
|
|
API.ValueStringData(@tmpVal, strData, strLen);
|
|
|
|
API.ValueNthElementValue(@pair, 1, tmpVal);
|
|
if (strData = 'm_nick') then Contact.TmpNick := GetString;
|
|
if (strData = 'm_firstname') then Contact.First := GetString;
|
|
if (strData = 'm_lastname') then Contact.Last := GetString;
|
|
if (strData = 'm_email') then Contact.Email := GetString;
|
|
if (strData = 'm_gender') then Contact.Gender := GetInt;
|
|
if (strData = 'm_marital') then Contact.MarStatus := GetInt;
|
|
if (strData = 'm_lang1') then Contact.Lang[1] := GetString;
|
|
if (strData = 'm_lang2') then Contact.Lang[2] := GetString;
|
|
if (strData = 'm_lang3') then Contact.Lang[3] := GetString;
|
|
if (strData = 'm_age') then Birthday := GetInt = 1;
|
|
if (strData = 'm_birth') then if Birthday then Contact.Birth := GetDate else Contact.Birth := 0;
|
|
if (strData = 'm_birthlchk') then BirthLChk := GetBool;
|
|
if (strData = 'm_birthl') then
|
|
if BirthLChk and (Contact.BirthL > 0) then
|
|
Contact.age := YearsBetween(Now, Contact.BirthL)
|
|
else if Birthday and (Contact.Birth > 0) then
|
|
Contact.age := YearsBetween(Now, Contact.Birth);
|
|
if (strData = 'm_about') then Contact.About := GetString;
|
|
|
|
// if (strData = 'h_homepage') then Contact.homepage := GetString;
|
|
// if (strData = 'h_address') then Contact.address := GetString;
|
|
// if (strData = 'h_city') then Contact.City := GetString;
|
|
// if (strData = 'h_state') then Contact.State := GetString;
|
|
// if (strData = 'h_country') then Contact.Country := GetString;
|
|
// if (strData = 'h_zip') then Contact.zip := GetString;
|
|
if (strData = 'p_cellular') then Contact.Cellular := GetString;
|
|
if (strData = 'p_home') then Contact.Regular := GetString;
|
|
if (strData = 'h_sms') then Contact.SMSMobile := GetString;
|
|
// if (strData = 'h_pob_city') then Contact.birthcity := GetString;
|
|
// if (strData = 'h_pob_state') then Contact.birthstate := GetString;
|
|
// if (strData = 'h_pob_country') then Contact.birthCountry := GetString;
|
|
|
|
// if (strData = 'w_workpage') then Contact.workpage := GetString;
|
|
// if (strData = 'w_position') then Contact.WorkPos := GetString;
|
|
// if (strData = 'w_department') then Contact.WorkDep := GetString;
|
|
// if (strData = 'w_company') then Contact.WorkCompany := GetString;
|
|
// if (strData = 'w_address') then Contact.workaddress := GetString;
|
|
// if (strData = 'w_city') then Contact.workcity := GetString;
|
|
// if (strData = 'w_state') then Contact.workstate := GetString;
|
|
// if (strData = 'w_country') then Contact.workCountry := GetInt;
|
|
// if (strData = 'w_zip') then Contact.workzip := GetString;
|
|
if (strData = 'p_work') then Contact.WorkPhone := GetString;
|
|
if (strData = 'w_lifestatus') then Contact.LifeStatus := GetString;
|
|
|
|
if (strData = 'p_other') then Contact.OtherPhone := GetString;
|
|
{
|
|
if (strData = 'e_interest1') then Contact.interests.InterestBlock[0].Code := GetInt;
|
|
if (strData = 'e_interest2') then Contact.interests.InterestBlock[1].Code := GetInt;
|
|
if (strData = 'e_interest3') then Contact.interests.InterestBlock[2].Code := GetInt;
|
|
if (strData = 'e_interest4') then Contact.interests.InterestBlock[3].Code := GetInt;
|
|
|
|
if (strData = 'e_interest1s') and (Contact.interests.InterestBlock[0].Code > 0) then
|
|
begin
|
|
str2strings(',', GetString, Contact.interests.InterestBlock[0].Names);
|
|
inc(Contact.interests.count);
|
|
end;
|
|
if (strData = 'e_interest2s') and (Contact.interests.InterestBlock[1].Code > 0) then
|
|
begin
|
|
str2strings(',', GetString, Contact.interests.InterestBlock[1].Names);
|
|
inc(Contact.interests.count);
|
|
end;
|
|
if (strData = 'e_interest3s') and (Contact.interests.InterestBlock[2].Code > 0) then
|
|
begin
|
|
str2strings(',', GetString, Contact.interests.InterestBlock[2].Names);
|
|
inc(Contact.interests.count);
|
|
end;
|
|
if (strData = 'e_interest4s') and (Contact.interests.InterestBlock[3].Code > 0) then
|
|
begin
|
|
str2strings(',', GetString, Contact.interests.InterestBlock[3].Names);
|
|
inc(Contact.interests.count);
|
|
end;
|
|
}
|
|
end;
|
|
|
|
Account.AccProto.SendSaveMyInfo(Contact);
|
|
end;
|
|
|
|
class procedure TViewInfoMethods.UpdateBirthAge(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
var
|
|
Contact: TICQContact;
|
|
birthCheck, birthLCheck: Boolean;
|
|
birthVal, birthLVal: Double;
|
|
birth, birthL: TDateTime;
|
|
bindex, num, tmpInt: Integer;
|
|
blchk: Boolean;
|
|
valType: TSciterValueType;
|
|
valUType: Cardinal;
|
|
years: String;
|
|
begin
|
|
if argc < 4 then
|
|
Exit;
|
|
|
|
Contact := GetArgumentContact(argv);
|
|
if not Assigned(Contact) then
|
|
Exit;
|
|
|
|
birth := 0;
|
|
birthL := 0;
|
|
bindex := 0;
|
|
birthVal := 0;
|
|
birthLVal := 0;
|
|
birthCheck := False;
|
|
birthLCheck := False;
|
|
blchk := False;
|
|
|
|
Inc(argv);
|
|
API.ValueIntData(argv, bindex);
|
|
Inc(argv);
|
|
API.ValueIntData(argv, tmpInt);
|
|
blchk := tmpInt = 1;
|
|
|
|
Inc(argv);
|
|
API.ValueType(argv, valType, valUType);
|
|
if valType = T_FLOAT then
|
|
begin
|
|
API.ValueFloatData(argv, birthVal);
|
|
try
|
|
birth := Trunc(UnixToDateTime(Trunc(birthVal), False));
|
|
birthCheck := True;
|
|
except
|
|
birth := 0;
|
|
birthCheck := False;
|
|
end;
|
|
end;
|
|
|
|
Inc(argv);
|
|
API.ValueType(argv, valType, valUType);
|
|
if valType = T_FLOAT then
|
|
begin
|
|
API.ValueFloatData(argv, birthLVal);
|
|
try
|
|
birthL := Trunc(UnixToDateTime(Trunc(birthLVal), False));
|
|
birthLCheck := True;
|
|
except
|
|
birthL := 0;
|
|
birthLCheck := False;
|
|
end;
|
|
end;
|
|
|
|
if bindex = 0 then
|
|
birth := 0;
|
|
|
|
if blchk then
|
|
Contact.birthL := birthL
|
|
else
|
|
Contact.birthL := 0;
|
|
|
|
years := '';
|
|
num := 0;
|
|
|
|
if birthLCheck and blchk then
|
|
num := YearsBetween(now, Contact.birthL)
|
|
else if birthCheck and (bindex = 1) then
|
|
num := YearsBetween(now, birth);
|
|
|
|
if not (num = 0) then
|
|
years := IntToStr(num) + GetYearsWord(num);
|
|
|
|
V2S(years, retval);
|
|
end;
|
|
|
|
class procedure TViewInfoMethods.LoadAvatarAsync(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
var
|
|
Contact: TICQContact;
|
|
begin
|
|
Contact := GetArgumentContact(argv);
|
|
if Assigned(Contact) then
|
|
begin
|
|
reqAvatarsQ.Add(Contact);
|
|
ActionManager.Execute(AK_PROCESSAVATARDOWNLOAD);
|
|
end;
|
|
end;
|
|
|
|
class procedure TViewInfoMethods.LoadThumb(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
var
|
|
FileName: String;
|
|
FileStr: TMemoryStream;
|
|
Contact: TICQContact;
|
|
begin
|
|
Contact := GetArgumentContact(argv);
|
|
if not Assigned(Contact) then
|
|
Exit;
|
|
|
|
RemoveAllContactAorP(Contact, 1);
|
|
FileName := AccPath + avtPath + Contact.UID + '.photo.jpeg';
|
|
LoadFromURLAsFile(ICQ_THUMB_URL + Contact.UID, FileName, True);
|
|
|
|
if FileExists(FileName) then
|
|
begin
|
|
FileStr := TMemoryStream.Create;
|
|
FileStr.LoadFromFile(FileName);
|
|
if not IsSupportedPicFile(ExtractFileName(FileName)) or (DetectFileFormatStream(FileStr) = PA_FORMAT_UNK) then
|
|
begin
|
|
DeleteFile(FileName);
|
|
ShowAvatarError(Contact);
|
|
end else
|
|
FindAndSaveVibrantColors(1, FileStr, Contact);
|
|
FileStr.Free;
|
|
end;
|
|
|
|
UpdateAnP(Contact);
|
|
UpdateAnPFor(Contact);
|
|
end;
|
|
|
|
class procedure TViewInfoMethods.LoadPhoto(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
var
|
|
FileName: String;
|
|
FileStr: TMemoryStream;
|
|
Contact: TICQContact;
|
|
begin
|
|
Contact := GetArgumentContact(argv);
|
|
if not Assigned(Contact) then
|
|
Exit;
|
|
|
|
RemoveAllContactAorP(Contact, 1);
|
|
FileName := AccPath + avtPath + Contact.UID + '.photo.jpeg';
|
|
LoadFromURLAsFile(Format(ICQ_PHOTO_AVATAR, [Contact.UID, Contact.gender]), FileName, True);
|
|
|
|
if FileExists(FileName) then
|
|
begin
|
|
FileStr := TMemoryStream.Create;
|
|
FileStr.LoadFromFile(FileName);
|
|
if not IsSupportedPicFile(ExtractFileName(FileName)) or (DetectFileFormatStream(FileStr) = PA_FORMAT_UNK) then
|
|
begin
|
|
DeleteFile(FileName);
|
|
ShowAvatarError(Contact);
|
|
end else
|
|
FindAndSaveVibrantColors(1, FileStr, Contact);
|
|
FileStr.Free;
|
|
end;
|
|
|
|
UpdateAnP(Contact);
|
|
UpdateAnPFor(Contact);
|
|
end;
|
|
|
|
class procedure TViewInfoMethods.ClearAvatarOrPhoto(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
var
|
|
PicType: Integer;
|
|
Contact: TICQContact;
|
|
begin
|
|
Contact := GetArgumentContact(argv);
|
|
if not Assigned(Contact) then
|
|
Exit;
|
|
|
|
Inc(argv);
|
|
PicType := 0;
|
|
if argc > 0 then
|
|
API.ValueIntData(argv, PicType);
|
|
|
|
ClearAoP(Contact, PicType);
|
|
end;
|
|
|
|
class procedure TViewInfoMethods.ChangeAvatar(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
begin
|
|
OpenURL('https://www.icq.com/people/' + Account.AccProto.MyAccNum + '/edit/');
|
|
end;
|
|
|
|
class procedure TViewInfoMethods.GetCaptionColors(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
var
|
|
Contact: TICQContact;
|
|
begin
|
|
Contact := GetArgumentContact(argv);
|
|
if Assigned(Contact) then
|
|
V2S(UI.RecordToVar(Contact.IconColors), retval);
|
|
end;
|
|
|
|
class procedure TViewInfoMethods.SetIconShowType(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
var
|
|
ShowType: Integer;
|
|
Contact: TICQContact;
|
|
begin
|
|
Contact := GetArgumentContact(argv);
|
|
if not Assigned(Contact) then
|
|
Exit;
|
|
|
|
Inc(argv);
|
|
ShowType := 0;
|
|
API.ValueIntData(argv, showType);
|
|
case ShowType of
|
|
0: Contact.icon.ToShow := IS_AVATAR;
|
|
1: Contact.icon.ToShow := IS_PHOTO;
|
|
2: Contact.icon.ToShow := IS_NONE;
|
|
end;
|
|
UpdateAnP(Contact);
|
|
UpdateAnPFor(Contact);
|
|
end;
|
|
|
|
class procedure TViewInfoMethods.SetNoDBDelete(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
var
|
|
val: Integer;
|
|
Contact: TICQContact;
|
|
begin
|
|
Contact := GetArgumentContact(argv);
|
|
if not Assigned(Contact) then
|
|
Exit;
|
|
Inc(argv);
|
|
val := 0;
|
|
API.ValueIntData(argv, val);
|
|
TCE(Contact.Data^).DontDelete := val = 1;
|
|
end;
|
|
|
|
class procedure TViewInfoMethods.SetTranslit(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
var
|
|
val: Integer;
|
|
Contact: TICQContact;
|
|
begin
|
|
if argc = 0 then
|
|
Exit;
|
|
|
|
Contact := GetArgumentContact(argv);
|
|
if not Assigned(Contact) then
|
|
Exit;
|
|
|
|
Inc(argv);
|
|
val := 0;
|
|
API.ValueIntData(argv, val);
|
|
Contact.SendTransl := val = 1;
|
|
|
|
if Assigned(UI.Chat) then
|
|
UI.Chat.UpdateStatusBar;
|
|
end;
|
|
|
|
class procedure TViewInfoMethods.ApplyInfoStatus(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
var
|
|
str: PWideChar;
|
|
strLen: UINT;
|
|
begin
|
|
if argc = 0 then
|
|
Exit;
|
|
|
|
API.ValueStringData(argv, str, strLen);
|
|
if OnlFeature(Account.AccProto) then
|
|
// TODO: Send life status to server
|
|
//Account.AccProto.SendInfoStatus(str);
|
|
end;
|
|
|
|
class procedure TViewInfoMethods.ApplyNotes(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
var
|
|
str: PWideChar;
|
|
strLen: UINT;
|
|
Contact: TICQContact;
|
|
begin
|
|
Contact := GetArgumentContact(argv);
|
|
if not Assigned(Contact) then
|
|
Exit;
|
|
|
|
if not Contact.CntIsLocal then
|
|
if not OnlFeature(Account.AccProto) then
|
|
Exit;
|
|
|
|
with Contact do
|
|
begin
|
|
Inc(argv);
|
|
str := '';
|
|
API.ValueStringData(argv, str, strLen);
|
|
ssImportant := str;
|
|
Inc(argv);
|
|
API.ValueStringData(argv, str, strLen);
|
|
ssNickname := str;
|
|
Inc(argv);
|
|
API.ValueStringData(argv, str, strLen);
|
|
ssCell1 := str;
|
|
Inc(argv);
|
|
API.ValueStringData(argv, str, strLen);
|
|
ssCell2 := str;
|
|
Inc(argv);
|
|
API.ValueStringData(argv, str, strLen);
|
|
ssCell3 := str;
|
|
Inc(argv);
|
|
API.ValueStringData(argv, str, strLen);
|
|
ssCell4 := str;
|
|
end;
|
|
|
|
if not Contact.CntIsLocal then
|
|
Account.AccProto.SendContactAttrs(Contact);
|
|
end;
|
|
|
|
class procedure TViewInfoMethods.VerifyPhone(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
begin
|
|
OpenURL('https://icq.com/attach-phone/');
|
|
end;
|
|
|
|
class procedure TViewInfoMethods.SaveLocalInfo(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
var
|
|
Tmp: PWideChar;
|
|
StrLen: Cardinal;
|
|
Changed: Boolean;
|
|
Contact: TICQContact;
|
|
m_display, nl_important, nl_notes: String;
|
|
begin
|
|
Contact := GetArgumentContact(argv);
|
|
if not Assigned(Contact) then
|
|
Exit;
|
|
|
|
Inc(argv);
|
|
Tmp := '';
|
|
API.ValueStringData(argv, Tmp, StrLen);
|
|
m_display := Tmp;
|
|
Inc(argv);
|
|
API.ValueStringData(argv, Tmp, StrLen);
|
|
nl_important := Tmp;
|
|
Inc(argv);
|
|
API.ValueStringData(argv, Tmp, StrLen);
|
|
nl_notes := Tmp;
|
|
|
|
Changed := False;
|
|
if not (m_display = Contact.Display) then
|
|
begin
|
|
Contact.SetDisplay(m_display);
|
|
if Assigned(UI.Chat) then
|
|
UI.Chat.UserChanged(contact);
|
|
Changed := True;
|
|
end;
|
|
|
|
if not (nl_important = Contact.lclImportant) then
|
|
begin
|
|
Contact.lclImportant := nl_important;
|
|
Changed := True;
|
|
end;
|
|
|
|
TCE(Contact.data^).Notes := nl_notes;
|
|
UI.CL.UpdateContact(contact);
|
|
|
|
if Changed then
|
|
ActionManager.Execute(AK_UPDATEDB, 1000);
|
|
end;
|
|
|
|
class procedure TViewInfoMethods.GetContactViewInfoData(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
|
|
function DateTime2Str(dt: Tdatetime): string; overload;
|
|
begin
|
|
Result := DateTimeToStrMinMax(dt, { 1980 } 80 * 365, now)
|
|
end;
|
|
|
|
// procedure StreamToVariant(Stream: TMemoryStream; var v: OleVariant);
|
|
// var
|
|
// p : pointer;
|
|
// begin
|
|
// v := VarArrayCreate([0, Stream.Size - 1], varByte);
|
|
// p := VarArrayLock(v);
|
|
// Stream.Position := 0;
|
|
// Stream.Read(p^, Stream.Size);
|
|
// VarArrayUnlock(v);
|
|
// end;
|
|
|
|
var
|
|
Contact: TICQContact;
|
|
InfoData: TViewInfoData;
|
|
Values: TViewInfoContactData;
|
|
|
|
uinlist, tmpCaps, tmpHEXCaps: TStringList;
|
|
pubKey: AnsiString;
|
|
caps: array of TCap;
|
|
cap: RawByteString;
|
|
i: Integer;
|
|
begin
|
|
Contact := GetArgumentContact(argv);
|
|
if not Assigned(Contact) then
|
|
Exit;
|
|
|
|
with Contact do
|
|
begin
|
|
InfoData.caption := GenerateCaption(Contact);
|
|
InfoData.statusImg := StatusImg;
|
|
InfoData.xstatus := XStatus;
|
|
InfoData.xstatustext := XStatus2Text(XStatus);
|
|
InfoData.userType := Integer(UserType);
|
|
|
|
Values.m_display := Display;
|
|
Values.m_nick := Nick;
|
|
Values.m_firstname := First;
|
|
Values.m_lastname := Last;
|
|
Values.m_uin := UID;
|
|
|
|
//if birth > 0 then
|
|
//try
|
|
// values[10] := TTimeZone.Local.ToLocalTime(birth);
|
|
// values[11] := 1;
|
|
//except
|
|
// values[10] := Now;
|
|
// values[11] := 1;
|
|
//end else
|
|
//begin
|
|
// values[10] := False;
|
|
// values[11] := 0;
|
|
//end;
|
|
|
|
if birthL <= 0 then
|
|
Values.m_birthl := False
|
|
else
|
|
Values.m_birthl := TTimeZone.Local.ToLocalTime(birthL);
|
|
|
|
if not (StatusStr = '') then
|
|
Values.m_status := StatusStr
|
|
else
|
|
Values.m_status := StatusNameExt2(Byte(Status), XStatusIndex);
|
|
|
|
Values.m_smsable := SMSable;
|
|
Values.m_about := About;
|
|
Values.p_cellular := Cellular;
|
|
Values.p_home := Regular;
|
|
Values.p_other := OtherPhone;
|
|
Values.p_sms := SMSMobile;
|
|
Values.p_work := WorkPhone;
|
|
//LifeStatus;
|
|
Values.a_showtype := Contact.icon.ToShow;
|
|
{
|
|
if interests.Count > 0 then
|
|
begin
|
|
values[45] := VarArrayCreate([0, 1], varVariant);
|
|
values[45][0] := interests.InterestBlock[0].Code;
|
|
values[45][1] := strings2str(', ', interests.InterestBlock[0].Names);
|
|
end;
|
|
|
|
if interests.Count > 1 then
|
|
begin
|
|
values[46] := VarArrayCreate([0, 1], varVariant);
|
|
values[46][0] := interests.InterestBlock[1].Code;
|
|
values[46][1] := strings2str(', ', interests.InterestBlock[1].Names);
|
|
end;
|
|
|
|
if interests.Count > 2 then
|
|
begin
|
|
values[47] := VarArrayCreate([0, 1], varVariant);
|
|
values[47][0] := interests.InterestBlock[2].Code;
|
|
values[47][1] := strings2str(', ', interests.InterestBlock[2].Names);
|
|
end;
|
|
|
|
if interests.Count > 3 then
|
|
begin
|
|
values[48] := VarArrayCreate([0, 1], varVariant);
|
|
values[48][0] := interests.InterestBlock[3].Code;
|
|
values[48][1] := strings2str(', ', interests.InterestBlock[3].Names);
|
|
end;
|
|
}
|
|
Values.e_lastmsgtime := DateTime2Str(TCE(data^).LastMsgTime);
|
|
Values.e_lastonlinetime := DateTime2Str(LastTimeSeenOnline);
|
|
Values.e_onlinesince := DateTime2Str(OnlineSince);
|
|
Values.e_regon := DateTime2Str(MemberSince);
|
|
Values.e_infoupd := DateTime2Str(LastInfoUpdate);
|
|
Values.e_lastinfoupd := DateTime2Str(InfoUpdatedTo);
|
|
if Contact.group = 0 then
|
|
Values.e_group := '(' + GetTranslation('None') + ')'
|
|
else
|
|
Values.e_group := groups.id2name(Contact.group);
|
|
uinlist := TStringList.Create;
|
|
uinlists.resetEnumeration;
|
|
while uinlists.hasMore do
|
|
with uinlists.getNext^ do
|
|
if cl.exists(Contact) then
|
|
uinlist.add(name);
|
|
Values.e_uinlists := uinlist.Text;
|
|
uinlist.Free;
|
|
|
|
Values.e_nodbdelete := TCE(data^).DontDelete;
|
|
|
|
if Account.AccProto.IsMyAcc(Contact) then
|
|
Values.c_attachedmail := AttachedLoginPhone
|
|
else
|
|
Values.c_attachedmail := '';
|
|
|
|
Values.c_client := Contact.ClientDesc;
|
|
if Values.c_client = '' then
|
|
Values.c_client := GetTranslation(Str_unk);
|
|
|
|
Values.c_translit := SendTransl;
|
|
|
|
tmpCaps := TStringList.Create;
|
|
tmpHEXCaps := TStringList.Create;
|
|
|
|
for i in capabilitiesSm do
|
|
begin
|
|
tmpCaps.Append(GetTranslation(CapsSmall[i].s));
|
|
tmpHEXCaps.Append(str2hex(CapsSmall[i].v));
|
|
end;
|
|
|
|
for i in capabilitiesBig do
|
|
begin
|
|
tmpCaps.Append(GetTranslation(BigCapability[i].s));
|
|
tmpHEXCaps.Append(str2hex(BigCapability[i].v));
|
|
end;
|
|
|
|
if Length(extracapabilities) > 15 then
|
|
for i := 0 to Length(extracapabilities) div 16 - 1 do
|
|
begin
|
|
cap := copy(extracapabilities, i * 16 + 1, 16);
|
|
if AnsiStartsStr(CapsCustomBuild, cap) then
|
|
tmpCaps.Append(GetTranslation('R&Q build by Mikanoshi'))
|
|
else
|
|
tmpCaps.Append(GetTranslation('[Unknown]') + ' ' + BetterStr(cap));
|
|
tmpHEXCaps.Append(str2Hex(cap));
|
|
end;
|
|
|
|
try
|
|
SetLength(caps, tmpCaps.Count);
|
|
pubKey := Contact.Crypt.EccPubKey;
|
|
for i := 0 to tmpCaps.Count - 1 do
|
|
begin
|
|
var hex := Copy(tmpHEXCaps.Strings[i], 1, 10);
|
|
if (not (pubKey = '') and
|
|
((hex = '5244454330') or
|
|
(hex = '5244454331') or
|
|
(hex = '5244454332'))) then
|
|
else
|
|
begin
|
|
caps[i].HEX := tmpHEXCaps.Strings[i];
|
|
caps[i].Desc := tmpCaps.Strings[i];
|
|
end;
|
|
end;
|
|
|
|
if not (pubKey = '') then
|
|
begin
|
|
SetLength(caps, Length(caps) + 1);
|
|
caps[Length(caps) - 1].HEX := '--------------------------------';
|
|
caps[Length(caps) - 1].Desc := '' + GetTranslation('Public encryption key') + '';
|
|
end;
|
|
|
|
TArray.Sort |
|
function(const Left, Right: TCap): Integer
|
|
begin
|
|
Result := TComparer |
|
end));
|
|
|
|
Values.caps_desc := '';
|
|
Values.caps_hex := '';
|
|
for i := 0 to Length(caps) - 1 do
|
|
if not (caps[i].Desc = '') then
|
|
begin
|
|
Values.caps_desc := Values.caps_desc + caps[i].Desc + CRLF;
|
|
Values.caps_hex := Values.caps_hex + caps[i].HEX + CRLF;
|
|
end;
|
|
finally
|
|
tmpCaps.Free;
|
|
tmpHEXCaps.Free;
|
|
end;
|
|
|
|
Values.ns_important := ssImportant;
|
|
Values.ns_nickname := ssNickname;
|
|
Values.ns_sms := ssCell1;
|
|
Values.ns_cell1 := ssCell2;
|
|
Values.ns_cell2 := ssCell3;
|
|
Values.ns_cell3 := ssCell4;
|
|
Values.nl_important := lclImportant;
|
|
Values.nl_notes := TCE(data^).notes;
|
|
|
|
InfoData.values := UI.RecordToVar(Values);
|
|
|
|
V2S(UI.RecordToVar(InfoData), retval);
|
|
end;
|
|
end;
|
|
|
|
end.
|