Skip to content

Commit

Permalink
Import vcf from files
Browse files Browse the repository at this point in the history
Signed-off-by: John Molakvoæ (skjnldsv) <skjnldsv@protonmail.com>
  • Loading branch information
skjnldsv committed Jul 14, 2020
1 parent f100a47 commit fa9c884
Show file tree
Hide file tree
Showing 21 changed files with 160 additions and 46 deletions.
14 changes: 7 additions & 7 deletions css/icons.scss
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,17 @@
*
*/


@include icon-black-white('social', 'contacts', 1);
@include icon-black-white('qrcode', 'contacts', 1);
@include icon-black-white('address-book', 'contacts', 1);
@include icon-black-white('phone', 'contacts', 1);
@include icon-black-white('clone', 'contacts', 2);
@include icon-black-white('contacts', 'contacts', 1);
@include icon-black-white('eye', 'contacts', 1);
@include icon-black-white('up', 'contacts', 1);
@include icon-black-white('no-calendar', 'contacts', 1);
@include icon-black-white('language', 'contacts', 2);
@include icon-black-white('clone', 'contacts', 2);
@include icon-black-white('no-calendar', 'contacts', 1);
@include icon-black-white('phone', 'contacts', 1);
@include icon-black-white('qrcode', 'contacts', 1);
@include icon-black-white('recent-actors', 'contacts', 1);
@include icon-black-white('social', 'contacts', 1);
@include icon-black-white('up', 'contacts', 1);

.icon-up-force-white {
// using #fffffe to trick the accessibility dark theme icon invert
Expand Down
Binary file removed img/app.png
Binary file not shown.
4 changes: 4 additions & 0 deletions img/contacts.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 0 additions & 2 deletions img/favicon-mask.svg

This file was deleted.

Binary file removed img/favicon-touch.png
Binary file not shown.
2 changes: 0 additions & 2 deletions img/favicon-touch.svg

This file was deleted.

Binary file removed img/favicon.ico
Binary file not shown.
Binary file removed img/favicon.png
Binary file not shown.
2 changes: 0 additions & 2 deletions img/favicon.svg

This file was deleted.

5 changes: 5 additions & 0 deletions lib/AppInfo/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
namespace OCA\Contacts\AppInfo;

use OCA\Contacts\Dav\PatchPlugin;
use OCA\Contacts\Listener\LoadContactsFilesActions;
use OCA\Files\Event\LoadAdditionalScriptsEvent;
use OCP\AppFramework\App;
use OCP\EventDispatcher\IEventDispatcher;
use OCP\SabrePluginEvent;
Expand All @@ -49,5 +51,8 @@ public function register() {
$server->addPlugin($this->getContainer()->query(PatchPlugin::class));
}
});

// Register files action
$eventDispatcher->addServiceListener(LoadAdditionalScriptsEvent::class, LoadContactsFilesActions::class);
}
}
1 change: 0 additions & 1 deletion lib/Dav/PatchPlugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@
use Sabre\DAV\ServerPlugin;
use Sabre\HTTP\RequestInterface;
use Sabre\HTTP\ResponseInterface;
use Sabre\VObject\Component\VCard;
use Sabre\VObject\Reader;

class PatchPlugin extends ServerPlugin {
Expand Down
44 changes: 44 additions & 0 deletions lib/Listener/LoadContactsFilesActions.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php

declare(strict_types=1);

/**
* @copyright Copyright (c) 2020, John Molakvoæ <skjnldsv@protonmail.com>
*
* @author John Molakvoæ <skjnldsv@protonmail.com>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/

namespace OCA\Contacts\Listener;

use OCA\Contacts\AppInfo\Application;
use OCA\Files\Event\LoadAdditionalScriptsEvent;
use OCP\EventDispatcher\Event;
use OCP\EventDispatcher\IEventListener;
use OCP\Util;

class LoadContactsFilesActions implements IEventListener {
public function handle(Event $event): void {
if (!($event instanceof LoadAdditionalScriptsEvent)) {
return;
}

Util::addStyle(Application::APP_ID, 'icons');
Util::addScript(Application::APP_ID, 'contacts-files-action');
}
}
4 changes: 2 additions & 2 deletions src/components/ContactDetails.vue
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,15 @@
<template>
<div id="contact-details" class="app-content-details">
<!-- nothing selected or contact not found -->
<EmptyContent v-if="!contact && !loading" icon="icon-contacts-dark">
<EmptyContent v-if="!contact && !loading" icon="icon-contacts">
{{ t('contacts', 'No contact selected') }}
<template #desc>
{{ t('contacts', 'Select a contact on the list to begin') }}
</template>
</EmptyContent>

<!-- loading -->
<EmptyContent v-else-if="loading" icon="icon-contacts-dark">
<EmptyContent v-else-if="loading" icon="icon-contacts">
{{ t('contacts', 'Loading contacts …') }}
</EmptyContent>

Expand Down
2 changes: 1 addition & 1 deletion src/components/ProcessingScreen.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<template>
<EmptyContent class="processing-screen__wrapper" icon="icon-contacts-dark">
<EmptyContent class="processing-screen__wrapper" icon="icon-contacts">
<slot />
<template #desc>
<div class="processing-screen__progress">
Expand Down
2 changes: 1 addition & 1 deletion src/components/Properties/PropertyGroups.vue
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
<template>
<div v-if="propModel" class="grid-span-2 property property--without-actions">
<PropertyTitle
icon="icon-contacts-dark"
icon="icon-contacts"
:readable-name="t('contacts', 'Groups')" />

<div class="property__row">
Expand Down
52 changes: 37 additions & 15 deletions src/components/Settings/SettingsImportContacts.vue
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,20 @@ export default {
return this.importState.stage !== 'default'
},
},

async mounted() {
// Direct import check
if (this.$route.name === 'import') {
const path = this.$route.query.file
this.processLocalFile(path)

this.$router.push({
name: 'group',
params: { selectedGroup: t('contacts', 'All contacts') },
})
}
},

methods: {
/**
* Process input type file change
Expand All @@ -196,6 +210,27 @@ export default {
reader.readAsText(file)
},

async processLocalFile(path) {
try {
// prepare cancel token for axios request
const source = CancelToken.source()
this.cancelRequest = source.cancel

const file = await axios.get(generateRemoteUrl(`dav/files/${getCurrentUser().uid}`) + encodePath(path), {
cancelToken: source.token,
})

this.$store.dispatch('changeStage', 'parsing')
this.$store.dispatch('setAddressbook', this.selectedAddressbook.displayName)

if (file.data) {
await this.$store.dispatch('importContactsIntoAddressbook', { vcf: file.data, addressbook: this.selectedAddressbook })
}
} catch (error) {
console.error('Something wrong happened while processing local file', error)
}
},

toggleModal() {
this.isOpened = !this.isOpened
// cancel any ongoing request if closed
Expand All @@ -217,22 +252,9 @@ export default {
// unlikely, but let's cancel any previous request
this.cancelRequest()

// prepare cancel token for axios request
const source = CancelToken.source()
this.cancelRequest = source.cancel

// pick and retrieve file
// pick, retrieve & process file
const path = await picker.pick()
const file = await axios.get(generateRemoteUrl(`dav/files/${getCurrentUser().uid}`) + encodePath(path), {
cancelToken: source.token,
})

this.$store.dispatch('changeStage', 'parsing')
this.$store.dispatch('setAddressbook', this.selectedAddressbook.displayName)

if (file.data) {
await this.$store.dispatch('importContactsIntoAddressbook', { vcf: file.data, addressbook: this.selectedAddressbook })
}
await this.processLocalFile(path)
} catch (error) {
console.error('Something wrong happened while picking a file', error)
} finally {
Expand Down
38 changes: 38 additions & 0 deletions src/files_action.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/**
* @copyright Copyright (c) 2020 John Molakvoæ <skjnldsv@protonmail.com>
*
* @author John Molakvoæ <skjnldsv@protonmail.com>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
import { generateUrl } from '@nextcloud/router'

window.addEventListener('DOMContentLoaded', () => {
if (OCA.Files && OCA.Files.fileActions) {
OCA.Files.fileActions.registerAction({
name: 'contacts_import',
displayName: t('contacts', 'Import'),
mime: 'text/vcard',
permissions: OC.PERMISSION_READ,
iconClass: 'icon-contacts',
actionHandler: function(fileName, context) {
const absPath = `${context.dir === '/' ? '' : context.dir}/${fileName}`
window.location = generateUrl(`/apps/contacts/import?file=${absPath}`)
},
})
}
})
5 changes: 5 additions & 0 deletions src/router/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@ export default new Router({
params: { selectedGroup: t('contacts', 'All contacts') },
},
children: [
{
path: 'import',
name: 'import',
component: Contacts,
},
{
path: ':selectedGroup',
name: 'group',
Expand Down
Loading

0 comments on commit fa9c884

Please sign in to comment.