Skip to content

Commit

Permalink
fixup! feat: add example contact on first login
Browse files Browse the repository at this point in the history
Signed-off-by: Hamza Mahjoubi <[email protected]>
  • Loading branch information
hamza221 committed Jan 23, 2025
1 parent 76cd083 commit 9101f07
Show file tree
Hide file tree
Showing 9 changed files with 3,628 additions and 65 deletions.
4 changes: 2 additions & 2 deletions apps/dav/appinfo/routes.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
['name' => 'invitation_response#decline', 'url' => '/invitation/decline/{token}', 'verb' => 'GET'],
['name' => 'invitation_response#options', 'url' => '/invitation/moreOptions/{token}', 'verb' => 'GET'],
['name' => 'invitation_response#processMoreOptionsResult', 'url' => '/invitation/moreOptions/{token}', 'verb' => 'POST'],
['name' => 'example_content#set_default_contact', 'url' => '/api/defaultcontact/contact', 'verb' => 'PUT'],
['name' => 'example_content#set-app-config', 'url' => '/api/defaultcontact/config', 'verb' => 'PUT'],
['name' => 'example_content#setDefaultContact', 'url' => '/api/defaultcontact/contact', 'verb' => 'PUT'],
['name' => 'example_content#setAppConfig', 'url' => '/api/defaultcontact/config/{key}', 'verb' => 'PUT'],
],
'ocs' => [
['name' => 'direct#getUrl', 'url' => '/api/v1/direct', 'verb' => 'POST'],
Expand Down
42 changes: 17 additions & 25 deletions apps/dav/lib/Controller/ExampleContentController.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,29 @@

namespace OCA\DAV\Controller;

use OCA\Contacts\AppInfo\Application;
use OCA\DAV\AppInfo\Application;
use OCP\App\IAppManager;
use OCP\AppFramework\ApiController;
use OCP\AppFramework\Http;
use OCP\AppFramework\Http\JSONResponse;
use OCP\Files\AppData\IAppDataFactory;
use OCP\Files\IAppData;
use OCP\Files\NotFoundException;
use OCP\IConfig;
use OCP\IRequest;

class ExampleContentController extends ApiController {

/** @var IAppData */
private $appData;
public function __construct(
IRequest $request,
private IConfig $config,
private IAppData $appData,
private IAppDataFactory $appDataFactory,
private IAppManager $appManager,
) {
parent::__construct(Application::APP_ID, $request);
$this->appData = $this->appDataFactory->get('dav');
}


Expand All @@ -44,44 +48,32 @@ public function setAppConfig($key, $allow) {
}

public function setDefaultContact($contactData) {
if (!$this->config->getAppValue(Application::APP_ID, 'enableDefaultContact', 'yes')) {
if (!$this->config->getAppValue(Application::APP_ID, 'enableDefaultContact', 'no')) {
return new JSONResponse([], Http::STATUS_FORBIDDEN);
}
$this->setCard($contactData);
return new JSONResponse([], Http::STATUS_OK);
}

private function setCard(?string $cardData = null) {
try {
$folder = $this->appData->getFolder('defaultContact');
} catch (NotFoundException $e) {
$folder = $this->appData->newFolder('defaultContact');
}
$file = (!$folder->fileExists('defaultContact.vcf')) ? $folder->newFile('defaultContact.vcf') : $folder->getFile('defaultContact.vcf');
$file->putContent($contactData);
return new JSONResponse([], Http::STATUS_OK);
}

private function setInitialDefaultContact() {
$cardData = 'BEGIN:VCARD' . PHP_EOL .
'VERSION:3.0' . PHP_EOL .
'PRODID:-//Nextcloud Contacts v' . $this->appManager->getAppVersion('contacts') . PHP_EOL .
'UID: janeDoe' . PHP_EOL .
'FN:Jane Doe' . PHP_EOL .
'ADR;TYPE=HOME:;;123 Street Street;City;State;;Country' . PHP_EOL .
'EMAIL;TYPE=WORK:[email protected]' . PHP_EOL .
'TEL;TYPE=HOME,VOICE:+999999999999' . PHP_EOL .
'TITLE:Manager' . PHP_EOL .
'ORG:Company' . PHP_EOL .
'BDAY;VALUE=DATE:20000101' . PHP_EOL .
'URL;VALUE=URI:https://example.com/' . PHP_EOL .
'REV;VALUE=DATE-AND-OR-TIME:20241227T144820Z' . PHP_EOL .
'END:VCARD';
$folder = $this->appData->getFolder('defaultContact');
$file = $folder->newFile('defaultContact.vcf');
if (is_null($cardData)) {
$cardData = file_get_contents(__DIR__ . '/../ExampleContentFiles/exampleContact.vcf');
}

$file = (!$folder->fileExists('defaultContact.vcf')) ? $folder->newFile('defaultContact.vcf') : $folder->getFile('defaultContact.vcf');
$file->putContent($cardData);
}

private function defaultContactExists(): bool {
try {
$folder = $this->appData->getFolder('defaultContact');
} catch (NotFoundException $e) {
$this->appData->newFolder('defaultContact');
return false;
}
return $folder->fileExists('defaultContact.vcf');
Expand Down
3,555 changes: 3,555 additions & 0 deletions apps/dav/lib/ExampleContentFiles/exampleContact.vcf

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion apps/dav/lib/Service/DefaultContactService.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public function __construct(
}

public function createDefaultContact(string $addressBookId): void {
$appData = $this->appDataFactory->get('contacts');
$appData = $this->appDataFactory->get('dav');
try {
$folder = $appData->getFolder('defaultContact');
$defaultContactFile = $folder->getFile('defaultContact.vcf');
Expand Down
24 changes: 7 additions & 17 deletions apps/dav/lib/Settings/ExampleContentSettings.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,10 @@
use OCP\AppFramework\Http\TemplateResponse;
use OCP\AppFramework\Services\IInitialState;
use OCP\IConfig;
use OCP\Settings\IDelegatedSettings;
use OCP\Settings\ISettings;

class ExampleContentSettings implements IDelegatedSettings {
class ExampleContentSettings implements ISettings {

private const defaults = [
'enableDefaultContact' => 'yes',
];

/**
* ExampleContentSettings constructor.
*
Expand All @@ -32,15 +28,15 @@ public function __construct(
}

public function getForm(): TemplateResponse {
$enableDefaultContact = $this->config->getAppValue(Application::APP_ID, 'enableDefaultContact', 'yes');
$this->initialState->provideInitialState(Application::APP_ID, 'enableDefaultContact', $enableDefaultContact);
$enableDefaultContact = $this->config->getAppValue(Application::APP_ID, 'enableDefaultContact', 'no');
$this->initialState->provideInitialState('enableDefaultContact', $enableDefaultContact);
return new TemplateResponse(Application::APP_ID, 'settings-example-content');
}

public function getSection(): ?string {
/* if (!$this->appManager->isEnabledForUser('contacts')) {
return null;
}*/
if (!$this->appManager->isEnabledForUser('contacts')) {
return null;
}

return 'groupware';
}
Expand All @@ -56,10 +52,4 @@ public function getName(): ?string {
return 'Example Content';
}

public function getAuthorizedAppConfig(): array {
return [
'dav' => ['/(' . implode('|', array_keys(self::defaults)) . ')/']
];
}

}
56 changes: 39 additions & 17 deletions apps/dav/src/views/ExampleContactSettings.vue
Original file line number Diff line number Diff line change
Expand Up @@ -21,21 +21,22 @@
<template #icon>
<IconUpload :size="20" />
</template>
{{ $t('contacts', 'Import contact') }}
{{ $t('dav', 'Import contact') }}
</NcButton>
<NcDialog :open.sync="isModalOpen"
:name="$t('contacts', 'Import contacts')"
:name="$t('dav', 'Import contacts')"
:buttons="buttons">
<div>
<p>{{ $t('dav', 'Importing a new .vcf file will delete the existing default contact and replace it with the new one. Do you want to continue?') }}</p>
<input id="contact-import"
ref="contact-import-input"
:disabled="loading"
type="file"
class="hidden-visually"
@change="processFile">
</div>
</NcDialog>
<input id="example-contact-import"
ref="exampleContactImportInput"
:disabled="loading"
type="file"
accept=".vcf"
class="hidden-visually"
@change="processFile">
</p>
</NcSettingsSection>
</template>
Expand All @@ -44,10 +45,12 @@ import axios from '@nextcloud/axios'
import { generateUrl } from '@nextcloud/router'
import { loadState } from '@nextcloud/initial-state'
import { NcDialog, NcButton, NcSettingsSection } from '@nextcloud/vue'
import { showSuccess } from '@nextcloud/dialogs'
import { showError, showSuccess } from '@nextcloud/dialogs'
import IconUpload from 'vue-material-design-icons/Upload.vue'
import IconCancel from '@mdi/svg/svg/cancel.svg'
import IconCheck from '@mdi/svg/svg/check.svg'
import IconCancel from '@mdi/svg/svg/cancel.svg?raw'
import IconCheck from '@mdi/svg/svg/check.svg?raw'

const enableDefaultContact = loadState('dav', 'enableDefaultContact') === 'yes'

export default {
name: 'ExampleContactSettings',
Expand All @@ -59,17 +62,17 @@ export default {
},
data() {
return {
enableDefaultContact: loadState('contacts', 'enableDefaultContact') === 'yes',
enableDefaultContact,
isModalOpen: false,
loading: false,
buttons: [
{
label: this.$t('contacts', 'Cancel'),
label: this.$t('dav', 'Cancel'),
icon: IconCancel,
callback: () => { this.isModalOpen = false },
},
{
label: this.$t('contacts', 'Import'),
label: this.$t('dav', 'Import'),
type: 'primary',
icon: IconCheck,
callback: () => { this.clickImportInput() },
Expand All @@ -81,28 +84,44 @@ export default {
updateEnableDefaultContact() {
axios.put(generateUrl('apps/dav/api/defaultcontact/config/{key}', { key: 'enableDefaultContact' }), {
allow: this.enableDefaultContact ? 'yes' : 'no',
}).catch(() => {
this.enableDefaultContact = !this.enableDefaultContact
showError(this.$t('dav', 'Error while saving settings'))
})
},
toggleModal() {
this.isModalOpen = !this.isModalOpen
},
clickImportInput() {
this.$refs['contact-import-input'].click()
this.$refs.exampleContactImportInput.click()
},

processFile(event) {
console.log('processFile triggered')
this.loading = true
console.log('Event:', event)

const file = event.target.files[0]
console.log('Selected file:', file)

const reader = new FileReader()

reader.onload = () => {
console.log('File content:', reader.result)
this.isModalOpen = false
axios.put(generateUrl('/apps/dav/api/defaultcontact/contact'), { contactData: reader.result })
.then(() => {
showSuccess(this.$t('dav', 'Contact imported successfully'))
})
.catch((error) => {
console.error('Error importing contact:', error)
showError(this.$t('dav', 'Error while importing contact'))
})
.finally(() => {
this.loading = false
})
event.target.value = ''
}
reader.readAsText(file)
showSuccess(this.$t('dav', 'Contact imported successfully'))
},
},
}
Expand All @@ -111,4 +130,7 @@ export default {
.import-button {
margin-top: 1rem;
}
.hidden-visually {
display: none;
}
</style>
Loading

0 comments on commit 9101f07

Please sign in to comment.