Added export contacts (vCard)

This commit is contained in:
RainLoop Team 2014-04-29 00:34:34 +04:00
parent c25b5bfef7
commit c248292f07
37 changed files with 489 additions and 237 deletions

View file

@ -227,6 +227,22 @@ LinkBuilder.prototype.getUserPicUrlFromHash = function (sHash)
return this.sServer + '/Raw/' + this.sSpecSuffix + '/UserPic/' + sHash + '/' + this.sVersion + '/';
};
/**
* @return {string}
*/
LinkBuilder.prototype.exportContactsVcf = function ()
{
return this.sServer + '/Raw/' + this.sSpecSuffix + '/ContactsVcf/';
};
/**
* @return {string}
*/
LinkBuilder.prototype.exportContactsCsv = function ()
{
return this.sServer + '/Raw/' + this.sSpecSuffix + '/ContactsCsv/';
};
/**
* @return {string}
*/

View file

@ -87,6 +87,9 @@ function WebMailDataStorage()
this.contacts.loading = ko.observable(false).extend({'throttle': 200});
this.contacts.importing = ko.observable(false).extend({'throttle': 200});
this.contacts.syncing = ko.observable(false).extend({'throttle': 200});
this.contacts.exportingVcf = ko.observable(false).extend({'throttle': 200});
this.contacts.exportingCsv = ko.observable(false).extend({'throttle': 200});
this.contacts.skipNextSync = false;
this.allowContactsSync = ko.observable(false);

View file

@ -19,6 +19,7 @@ function PopupsContactsViewModel()
this.allowContactsSync = RL.data().allowContactsSync;
this.enableContactsSync = RL.data().enableContactsSync;
this.allowExport = !Globals.bMobileDevice;
this.search = ko.observable('');
this.contactsCount = ko.observable(0);
@ -317,6 +318,16 @@ PopupsContactsViewModel.prototype.addNewPhone = function ()
this.addNewProperty(Enums.ContactPropertyType.Phone, 'Mobile');
};
PopupsContactsViewModel.prototype.exportVcf = function ()
{
RL.download(RL.link().exportContactsVcf());
};
PopupsContactsViewModel.prototype.exportCsv = function ()
{
RL.download(RL.link().exportContactsCsv());
};
PopupsContactsViewModel.prototype.initUploader = function ()
{
if (this.importUploaderButton())

View file

@ -2,7 +2,7 @@
"name": "RainLoop",
"title": "RainLoop Webmail",
"version": "1.6.5",
"release": "910",
"release": "911",
"description": "Simple, modern & fast web-based email client",
"homepage": "http://rainloop.net",
"main": "Gruntfile.js",

View file

@ -565,6 +565,15 @@ class Http
return $bResult;
}
public function ServerNoCache()
{
@\header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
@\header('Last-Modified: '.\gmdate('D, d M Y H:i:s').' GMT');
@\header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
@\header('Cache-Control: post-check=0, pre-check=0', false);
@\header('Pragma: no-cache');
}
/**
* @param int $iStatus
*

View file

@ -6116,6 +6116,42 @@ class Actions
return $this->rawSmart(false);
}
/**
* @return bool
*/
public function RawContactsVcf()
{
$oAccount = $this->getAccountFromToken();
\header('Content-Type: text/directory; charset=UTF-8');
\header('Content-Disposition: attachment; filename="contacts.vcf"', true);
\header('Accept-Ranges: none', true);
\header('Content-Transfer-Encoding: binary');
$this->oHttp->ServerNoCache();
return $this->AddressBookProvider($oAccount)->IsActive() ?
$this->AddressBookProvider($oAccount)->Export($oAccount->ParentEmailHelper(), 'vcf') : false;
}
/**
* @return bool
*/
public function RawContactsCsv()
{
$oAccount = $this->getAccountFromToken();
\header('Content-Type: ext/csv; charset=UTF-8');
\header('Content-Disposition: attachment; filename="contacts.csv"', true);
\header('Accept-Ranges: none', true);
\header('Content-Transfer-Encoding: binary');
$this->oHttp->ServerNoCache();
return $this->AddressBookProvider($oAccount)->IsActive() ?
$this->AddressBookProvider($oAccount)->Export($oAccount->ParentEmailHelper(), 'csv') : false;
}
/**
* @return bool
*/

View file

@ -75,6 +75,17 @@ class AddressBook extends \RainLoop\Providers\AbstractProvider
return $this->IsActive() ? $this->oDriver->Sync($sEmail, $sUrl, $sUser, $sPassword) : false;
}
/**
* @param string $sEmail
* @param string $sType = 'vcf'
*
* @return bool
*/
public function Export($sEmail, $sType = 'vcf')
{
return $this->IsActive() ? $this->oDriver->Export($sEmail, $sType) : false;
}
/**
* @param string $sEmail
* @param \RainLoop\Providers\AddressBook\Classes\Contact $oContact

View file

@ -265,6 +265,25 @@ class Contact
return (string) $oVCard->serialize();
}
/**
* @todo
* @return string
*/
public function ToCsvHeader()
{
return '';
}
/**
* @todo
* @return string
*/
public function ToCsvLine()
{
$this->UpdateDependentValues();
return '';
}
/**
* @param mixed $oProp
* @param bool $bOldVersion

View file

@ -362,6 +362,57 @@ class PdoAddressBook
return true;
}
/**
* @param string $sEmail
* @param string $sType = 'vcf'
*
* @return bool
*/
public function Export($sEmail, $sType = 'vcf')
{
$this->SyncDatabase();
$iUserID = $this->getUserId($sEmail);
if (0 >= $iUserID)
{
return false;
}
$bVcf = 'vcf' === $sType;
$bCsvHeader = false;
$aDatabaseSyncData = $this->prepearDatabaseSyncData($iUserID);
if (\is_array($aDatabaseSyncData) && 0 < \count($aDatabaseSyncData))
{
foreach ($aDatabaseSyncData as $mData)
{
if ($mData && isset($mData['id_contact'], $mData['deleted']) && !$mData['deleted'])
{
$oContact = $this->GetContactByID($sEmail, $mData['id_contact']);
if ($oContact)
{
if ($bVcf)
{
echo $oContact->ToVCard();
}
else
{
if (!$bCsvHeader)
{
$bCsvHeader = true;
echo $oContact->ToCsvHeader();
}
echo $oContact->ToCsvLine();
}
}
}
}
}
return true;
}
/**
* @param string $sEmail
* @param \RainLoop\Providers\AddressBook\Classes\Contact $oContact

View file

@ -156,6 +156,7 @@ class Service
else
{
@header('Content-Type: text/html; charset=utf-8');
$this->oHttp->ServerNoCache();
$aData = $this->startUpData($bAdmin);

View file

@ -950,11 +950,7 @@ class ServiceActions
private function localAppData($bAdmin = false)
{
@\header('Content-Type: application/javascript; charset=utf-8');
@\header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
@\header('Last-Modified: '.\gmdate('D, d M Y H:i:s').' GMT');
@\header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
@\header('Cache-Control: post-check=0, pre-check=0', false);
@\header('Pragma: no-cache');
$this->oHttp->ServerNoCache();
$sAuthAccountHash = '';
if (!$bAdmin)

View file

@ -12,21 +12,36 @@
</a>
</div>
<div class="btn-group">
<a class="btn dropdown-toggle buttonMore" data-toggle="dropdown">
<div class="btn-group dropdown" data-bind="registrateBootstrapDropdown: true">
<a id="contacts-more-dropdown-id" class="btn dropdown-toggle buttonMore" href="#" tabindex="-1" data-toggle="dropdown">
<i data-bind="css: {'icon-list': !contacts.importing() && !contacts.syncing(),
'icon-spinner animated': contacts.importing() || contacts.syncing()}"></i>
</a>
<ul class="dropdown-menu g-ui-menu" role="menu">
<li class="e-item">
<a class="e-link" data-bind="initDom: importUploaderButton">
<ul class="dropdown-menu g-ui-menu" role="menu" aria-labelledby="contacts-more-dropdown-id">
<li class="e-item" role="presentation">
<a class="e-link menuitem" href="#" tabindex="-1" data-bind="initDom: importUploaderButton">
<i data-bind="css: {'icon-list-add': !contacts.importing(), 'icon-spinner animated': contacts.importing}"></i>
&nbsp;&nbsp;
<span class="i18n" data-i18n-text="CONTACTS/BUTTON_IMPORT"></span>
</a>
</li>
<li class="e-item" data-bind="visible: enableContactsSync() && allowContactsSync()">
<a class="e-link" data-bind="command: syncCommand">
<!-- <li class="e-item" role="presentation" data-bind="visible: allowExport" >
<a class="e-link menuitem" href="#" tabindex="-1" data-bind="click: exportCsv">
<i data-bind="css: {'icon-download': !contacts.exportingCsv(), 'icon-spinner animated': contacts.exportingCsv}"></i>
&nbsp;&nbsp;
<span class="i18n" data-i18n-text="CONTACTS/BUTTON_EXPORT_CSV"></span>
</a>
</li>-->
<li class="e-item" role="presentation" data-bind="visible: allowExport" >
<a class="e-link menuitem" href="#" tabindex="-1" data-bind="click: exportVcf">
<i data-bind="css: {'icon-download': !contacts.exportingVcf(), 'icon-spinner animated': contacts.exportingVcf}"></i>
&nbsp;&nbsp;
<span class="i18n" data-i18n-text="CONTACTS/BUTTON_EXPORT_VCARD"></span>
</a>
</li>
<li class="divider" role="presentation" data-bind="visible: enableContactsSync() && allowContactsSync()"></li>
<li class="e-item" role="presentation" data-bind="visible: enableContactsSync() && allowContactsSync()">
<a class="e-link menuitem" href="#" tabindex="-1" data-bind="command: syncCommand">
<i data-bind="css: {'icon-sync': !contacts.syncing(), 'icon-spinner animated': contacts.syncing}"></i>
&nbsp;&nbsp;
<span class="i18n" data-i18n-text="CONTACTS/BUTTON_SYNC"></span>

View file

@ -152,7 +152,9 @@ SEARCH_INPUT_PLACEHOLDER = "Suche"
BUTTON_ADD_CONTACT = "Kontakt hinzufügen"
BUTTON_CREATE_CONTACT = "Kontakt anlegen"
BUTTON_UPDATE_CONTACT = "Kontakt aktualisieren"
BUTTON_IMPORT = "Import (csv, vcf, vcard)"
BUTTON_IMPORT = "Import (csv, vcf, vCard)"
BUTTON_EXPORT_VCARD = "Export (vcf, vCard)"
BUTTON_EXPORT_CSV = "Export (csv)"
ERROR_IMPORT_FILE = "Import error (invalid file format)"
LIST_LOADING = "es wird geladen"
EMPTY_LIST = "Keine Kontakte"

View file

@ -152,7 +152,9 @@ SEARCH_INPUT_PLACEHOLDER = "Search"
BUTTON_ADD_CONTACT = "Add Contact"
BUTTON_CREATE_CONTACT = "Create"
BUTTON_UPDATE_CONTACT = "Update"
BUTTON_IMPORT = "Import (csv, vcf, vcard)"
BUTTON_IMPORT = "Import (csv, vcf, vCard)"
BUTTON_EXPORT_VCARD = "Export (vcf, vCard)"
BUTTON_EXPORT_CSV = "Export (csv)"
ERROR_IMPORT_FILE = "Import error (invalid file format)"
LIST_LOADING = "Loading"
EMPTY_LIST = "No contacts here"

View file

@ -152,7 +152,9 @@ SEARCH_INPUT_PLACEHOLDER = "Buscar"
BUTTON_ADD_CONTACT = "Añadir Contacto"
BUTTON_CREATE_CONTACT = "Crear"
BUTTON_UPDATE_CONTACT = "Actualizar"
BUTTON_IMPORT = "Import (csv, vcf, vcard)"
BUTTON_IMPORT = "Import (csv, vcf, vCard)"
BUTTON_EXPORT_VCARD = "Export (vcf, vCard)"
BUTTON_EXPORT_CSV = "Export (csv)"
ERROR_IMPORT_FILE = "Import error (invalid file format)"
LIST_LOADING = "Cargando"
EMPTY_LIST = "No hay contactos aquí"

View file

@ -152,7 +152,9 @@ SEARCH_INPUT_PLACEHOLDER = "Recherche"
BUTTON_ADD_CONTACT = "Ajouter un contact"
BUTTON_CREATE_CONTACT = "Créer"
BUTTON_UPDATE_CONTACT = "Modifier"
BUTTON_IMPORT = "Importer (csv, vcf, vcard)"
BUTTON_IMPORT = "Importer (csv, vcf, vCard)"
BUTTON_EXPORT_VCARD = "Export (vcf, vCard)"
BUTTON_EXPORT_CSV = "Export (csv)"
ERROR_IMPORT_FILE = "Erreur d'importation (Format de fichier invalide)"
LIST_LOADING = "Chargement"
EMPTY_LIST = "Aucun contact"

View file

@ -152,7 +152,9 @@ SEARCH_INPUT_PLACEHOLDER = "Keresés"
BUTTON_ADD_CONTACT = "Új kapcsolat"
BUTTON_CREATE_CONTACT = "Létrehozás"
BUTTON_UPDATE_CONTACT = "Frissítés"
BUTTON_IMPORT = "Importálás (csv, vcf, vcard)"
BUTTON_IMPORT = "Importálás (csv, vcf, vCard)"
BUTTON_EXPORT_VCARD = "Export (vcf, vCard)"
BUTTON_EXPORT_CSV = "Export (csv)"
ERROR_IMPORT_FILE = "Importálás hiba (érvénytelen fájl formátum)"
LIST_LOADING = "Betöltés"
EMPTY_LIST = "Nincsenek kapcsolatok"

View file

@ -152,7 +152,9 @@ SEARCH_INPUT_PLACEHOLDER = "Leita"
BUTTON_ADD_CONTACT = "Bæta við tengilið"
BUTTON_CREATE_CONTACT = "Búa til"
BUTTON_UPDATE_CONTACT = "Uppfæra"
BUTTON_IMPORT = "Import (csv, vcf, vcard)"
BUTTON_IMPORT = "Import (csv, vcf, vCard)"
BUTTON_EXPORT_VCARD = "Export (vcf, vCard)"
BUTTON_EXPORT_CSV = "Export (csv)"
ERROR_IMPORT_FILE = "Import error (invalid file format)"
LIST_LOADING = "Hleð"
EMPTY_LIST = "Engir tengiliðir hér"

View file

@ -152,7 +152,9 @@ SEARCH_INPUT_PLACEHOLDER = "Cerca"
BUTTON_ADD_CONTACT = "Aggiungi contatto"
BUTTON_CREATE_CONTACT = "Crea"
BUTTON_UPDATE_CONTACT = "Aggiorna"
BUTTON_IMPORT = "Importa (csv, vcf, vcard)"
BUTTON_IMPORT = "Importa (csv, vcf, vCard)"
BUTTON_EXPORT_VCARD = "Export (vcf, vCard)"
BUTTON_EXPORT_CSV = "Export (csv)"
ERROR_IMPORT_FILE = "Errore di importazione (formato del file non valido)"
LIST_LOADING = "Caricamento..."
EMPTY_LIST = "Nessun contatto qui"

View file

@ -152,7 +152,9 @@ SEARCH_INPUT_PLACEHOLDER = "Search"
BUTTON_ADD_CONTACT = "Add Contact"
BUTTON_CREATE_CONTACT = "Create"
BUTTON_UPDATE_CONTACT = "Update"
BUTTON_IMPORT = "Import (csv, vcf, vcard)"
BUTTON_IMPORT = "Import (csv, vcf, vCard)"
BUTTON_EXPORT_VCARD = "Export (vcf, vCard)"
BUTTON_EXPORT_CSV = "Export (csv)"
ERROR_IMPORT_FILE = "Import error (invalid file format)"
LIST_LOADING = "Loading"
EMPTY_LIST = "No contacts here"

View file

@ -152,7 +152,9 @@ SEARCH_INPUT_PLACEHOLDER = "검색"
BUTTON_ADD_CONTACT = "연락처 추가"
BUTTON_CREATE_CONTACT = "연락처 추가"
BUTTON_UPDATE_CONTACT = "연락처 갱신"
BUTTON_IMPORT = "Import (csv, vcf, vcard)"
BUTTON_IMPORT = "Import (csv, vcf, vCard)"
BUTTON_EXPORT_VCARD = "Export (vcf, vCard)"
BUTTON_EXPORT_CSV = "Export (csv)"
ERROR_IMPORT_FILE = "Import error (invalid file format)"
LIST_LOADING = "여는중"
EMPTY_LIST = "연락처가 없습니다."

View file

@ -152,7 +152,9 @@ SEARCH_INPUT_PLACEHOLDER = "Meklēt"
BUTTON_ADD_CONTACT = "Pievienot kontaktu"
BUTTON_CREATE_CONTACT = "Izveidot"
BUTTON_UPDATE_CONTACT = "Atjaunot"
BUTTON_IMPORT = "Import (csv, vcf, vcard)"
BUTTON_IMPORT = "Import (csv, vcf, vCard)"
BUTTON_EXPORT_VCARD = "Export (vcf, vCard)"
BUTTON_EXPORT_CSV = "Export (csv)"
ERROR_IMPORT_FILE = "Import error (invalid file format)"
LIST_LOADING = "Lādējās"
EMPTY_LIST = "Nav kontaktu"

View file

@ -152,7 +152,9 @@ SEARCH_INPUT_PLACEHOLDER = "Zoeken"
BUTTON_ADD_CONTACT = "Contact Toevoegen"
BUTTON_CREATE_CONTACT = "Nieuw"
BUTTON_UPDATE_CONTACT = "Update"
BUTTON_IMPORT = "Import (csv, vcf, vcard)"
BUTTON_IMPORT = "Import (csv, vcf, vCard)"
BUTTON_EXPORT_VCARD = "Export (vcf, vCard)"
BUTTON_EXPORT_CSV = "Export (csv)"
ERROR_IMPORT_FILE = "Import error (invalid file format)"
LIST_LOADING = "Laden"
EMPTY_LIST = "Geen contacten hier"

View file

@ -152,7 +152,9 @@ SEARCH_INPUT_PLACEHOLDER = "Søk"
BUTTON_ADD_CONTACT = "Legg til kontakt"
BUTTON_CREATE_CONTACT = "Opprett"
BUTTON_UPDATE_CONTACT = "Oppdater"
BUTTON_IMPORT = "Import (csv, vcf, vcard)"
BUTTON_IMPORT = "Import (csv, vcf, vCard)"
BUTTON_EXPORT_VCARD = "Export (vcf, vCard)"
BUTTON_EXPORT_CSV = "Export (csv)"
ERROR_IMPORT_FILE = "Import error (invalid file format)"
LIST_LOADING = "Laster"
EMPTY_LIST = "Ingen kontakter her"

View file

@ -151,7 +151,9 @@ SEARCH_INPUT_PLACEHOLDER = "Szukaj"
BUTTON_ADD_CONTACT = "Dodaj Kontakt"
BUTTON_CREATE_CONTACT = "Utwórz"
BUTTON_UPDATE_CONTACT = "Aktualizuj"
BUTTON_IMPORT = "Import (csv, vcf, vcard)"
BUTTON_IMPORT = "Import (csv, vcf, vCard)"
BUTTON_EXPORT_VCARD = "Export (vcf, vCard)"
BUTTON_EXPORT_CSV = "Export (csv)"
ERROR_IMPORT_FILE = "Błąd importu (nieprawidłowy format pliku)"
LIST_LOADING = "Ładowanie"
EMPTY_LIST = "Brak kontaktów"

View file

@ -152,7 +152,9 @@ SEARCH_INPUT_PLACEHOLDER = "Procurar"
BUTTON_ADD_CONTACT = "Adicionar Contatos"
BUTTON_CREATE_CONTACT = "Criar"
BUTTON_UPDATE_CONTACT = "Atualizar"
BUTTON_IMPORT = "Import (csv, vcf, vcard)"
BUTTON_IMPORT = "Import (csv, vcf, vCard)"
BUTTON_EXPORT_VCARD = "Export (vcf, vCard)"
BUTTON_EXPORT_CSV = "Export (csv)"
ERROR_IMPORT_FILE = "Erro ao importat (formato do arquivo inválido)"
LIST_LOADING = "Carregando"
EMPTY_LIST = "Nenhum contato aqui"

View file

@ -152,7 +152,9 @@ SEARCH_INPUT_PLACEHOLDER = "Procurar"
BUTTON_ADD_CONTACT = "Adicionar Contatos"
BUTTON_CREATE_CONTACT = "Criar"
BUTTON_UPDATE_CONTACT = "Atualizar"
BUTTON_IMPORT = "Import (csv, vcf, vcard)"
BUTTON_IMPORT = "Import (csv, vcf, vCard)"
BUTTON_EXPORT_VCARD = "Export (vcf, vCard)"
BUTTON_EXPORT_CSV = "Export (csv)"
ERROR_IMPORT_FILE = "Erro ao importat (formato do arquivo inválido)"
LIST_LOADING = "Carregando"
EMPTY_LIST = "Nenhum contato aqui"

View file

@ -151,7 +151,9 @@ SEARCH_INPUT_PLACEHOLDER = "Caută contacte"
BUTTON_ADD_CONTACT = "Adugă un contact"
BUTTON_CREATE_CONTACT = "Salvează"
BUTTON_UPDATE_CONTACT = "Actualizează"
BUTTON_IMPORT = "Importă (csv, vcf, vcard)"
BUTTON_IMPORT = "Importă (csv, vcf, vCard)"
BUTTON_EXPORT_VCARD = "Export (vcf, vCard)"
BUTTON_EXPORT_CSV = "Export (csv)"
ERROR_IMPORT_FILE = "Nu s-a putut importa (formatul fișierului este greșit)"
LIST_LOADING = "Se încarcă..."
EMPTY_LIST = "Agenda este goală"

View file

@ -152,7 +152,9 @@ SEARCH_INPUT_PLACEHOLDER = "Поиск контактов"
BUTTON_ADD_CONTACT = "Добавить контакт"
BUTTON_CREATE_CONTACT = "Сохранить"
BUTTON_UPDATE_CONTACT = "Обновить"
BUTTON_IMPORT = "Импорт (csv, vcf, vcard)"
BUTTON_IMPORT = "Импорт (csv, vcf, vCard)"
BUTTON_EXPORT_VCARD = "Экспорт (vcf, vCard)"
BUTTON_EXPORT_CSV = "Экспорт (csv)"
ERROR_IMPORT_FILE = "Ошибка импорта (Неправильный формат файла)"
LIST_LOADING = "Загрузка"
EMPTY_LIST = "Нет контактов"

View file

@ -152,7 +152,9 @@ SEARCH_INPUT_PLACEHOLDER = "Hľadať"
BUTTON_ADD_CONTACT = "Pridať kontakt"
BUTTON_CREATE_CONTACT = "Vytvoriť"
BUTTON_UPDATE_CONTACT = "Aktualizovať"
BUTTON_IMPORT = "Importovať (csv, vcf, vcard)"
BUTTON_IMPORT = "Importovať (csv, vcf, vCard)"
BUTTON_EXPORT_VCARD = "Export (vcf, vCard)"
BUTTON_EXPORT_CSV = "Export (csv)"
ERROR_IMPORT_FILE = "Chyba importu (nesprávny formát súboru)"
LIST_LOADING = "Načítavam"
EMPTY_LIST = "Nemáte žiadne kontakty"

View file

@ -152,7 +152,9 @@ SEARCH_INPUT_PLACEHOLDER = "搜索"
BUTTON_ADD_CONTACT = "添加联系人"
BUTTON_CREATE_CONTACT = "新增联系人"
BUTTON_UPDATE_CONTACT = "更新联系人"
BUTTON_IMPORT = "Import (csv, vcf, vcard)"
BUTTON_IMPORT = "Import (csv, vcf, vCard)"
BUTTON_EXPORT_VCARD = "Export (vcf, vCard)"
BUTTON_EXPORT_CSV = "Export (csv)"
ERROR_IMPORT_FILE = "Import error (invalid file format)"
LIST_LOADING = "加载中"
EMPTY_LIST = "暂无联系人"

View file

@ -3557,6 +3557,22 @@ LinkBuilder.prototype.getUserPicUrlFromHash = function (sHash)
return this.sServer + '/Raw/' + this.sSpecSuffix + '/UserPic/' + sHash + '/' + this.sVersion + '/';
};
/**
* @return {string}
*/
LinkBuilder.prototype.exportContactsVcf = function ()
{
return this.sServer + '/Raw/' + this.sSpecSuffix + '/ContactsVcf/';
};
/**
* @return {string}
*/
LinkBuilder.prototype.exportContactsCsv = function ()
{
return this.sServer + '/Raw/' + this.sSpecSuffix + '/ContactsCsv/';
};
/**
* @return {string}
*/

File diff suppressed because one or more lines are too long

View file

@ -3561,6 +3561,22 @@ LinkBuilder.prototype.getUserPicUrlFromHash = function (sHash)
return this.sServer + '/Raw/' + this.sSpecSuffix + '/UserPic/' + sHash + '/' + this.sVersion + '/';
};
/**
* @return {string}
*/
LinkBuilder.prototype.exportContactsVcf = function ()
{
return this.sServer + '/Raw/' + this.sSpecSuffix + '/ContactsVcf/';
};
/**
* @return {string}
*/
LinkBuilder.prototype.exportContactsCsv = function ()
{
return this.sServer + '/Raw/' + this.sSpecSuffix + '/ContactsCsv/';
};
/**
* @return {string}
*/
@ -9658,6 +9674,7 @@ function PopupsContactsViewModel()
this.allowContactsSync = RL.data().allowContactsSync;
this.enableContactsSync = RL.data().enableContactsSync;
this.allowExport = !Globals.bMobileDevice;
this.search = ko.observable('');
this.contactsCount = ko.observable(0);
@ -9956,6 +9973,16 @@ PopupsContactsViewModel.prototype.addNewPhone = function ()
this.addNewProperty(Enums.ContactPropertyType.Phone, 'Mobile');
};
PopupsContactsViewModel.prototype.exportVcf = function ()
{
RL.download(RL.link().exportContactsVcf());
};
PopupsContactsViewModel.prototype.exportCsv = function ()
{
RL.download(RL.link().exportContactsCsv());
};
PopupsContactsViewModel.prototype.initUploader = function ()
{
if (this.importUploaderButton())
@ -15137,6 +15164,9 @@ function WebMailDataStorage()
this.contacts.loading = ko.observable(false).extend({'throttle': 200});
this.contacts.importing = ko.observable(false).extend({'throttle': 200});
this.contacts.syncing = ko.observable(false).extend({'throttle': 200});
this.contacts.exportingVcf = ko.observable(false).extend({'throttle': 200});
this.contacts.exportingCsv = ko.observable(false).extend({'throttle': 200});
this.contacts.skipNextSync = false;
this.allowContactsSync = ko.observable(false);

File diff suppressed because one or more lines are too long