feat: add bluesky to accounts, show the same in profile edit and visibility option, in view profile and also in sharing tab
Signed-off-by: yemkareems <yemkareems@gmail.com>pull/54069/head
parent
3dac5b33ee
commit
aa227f1c55
@ -0,0 +1,64 @@ |
||||
<!-- |
||||
- SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors |
||||
- SPDX-License-Identifier: AGPL-3.0-or-later |
||||
--> |
||||
|
||||
<template> |
||||
<AccountPropertySection v-bind.sync="value" |
||||
:readable="readable" |
||||
:on-validate="onValidate" |
||||
:placeholder="t('settings', 'Bluesky handle')" /> |
||||
</template> |
||||
|
||||
<script setup lang="ts"> |
||||
import type { AccountProperties } from '../../constants/AccountPropertyConstants.js' |
||||
|
||||
import { loadState } from '@nextcloud/initial-state' |
||||
import { t } from '@nextcloud/l10n' |
||||
import { ref } from 'vue' |
||||
import { NAME_READABLE_ENUM } from '../../constants/AccountPropertyConstants.ts' |
||||
import AccountPropertySection from './shared/AccountPropertySection.vue' |
||||
|
||||
const { bluesky } = loadState<AccountProperties>('settings', 'personalInfoParameters') |
||||
|
||||
const value = ref({ ...bluesky }) |
||||
const readable = NAME_READABLE_ENUM[bluesky.name] |
||||
|
||||
/** |
||||
* Validate that the text might be a bluesky handle |
||||
* @param text The potential bluesky handle |
||||
*/ |
||||
function onValidate(text: string): boolean { |
||||
if (text === '') return true; |
||||
|
||||
const lowerText = text.toLowerCase(); |
||||
|
||||
if (lowerText === 'bsky.social') { |
||||
// Standalone bsky.social is invalid |
||||
return false; |
||||
} |
||||
|
||||
if (lowerText.endsWith('.bsky.social')) { |
||||
// Enforce format: exactly one label + '.bsky.social' |
||||
const parts = lowerText.split('.'); |
||||
|
||||
// Must be in form: [username, 'bsky', 'social'] |
||||
if (parts.length !== 3 || parts[1] !== 'bsky' || parts[2] !== 'social') { |
||||
return false; |
||||
} |
||||
|
||||
const username = parts[0]; |
||||
const validateRegex = /^[a-z0-9][a-z0-9-]{2,17}$/; |
||||
return validateRegex.test(username); |
||||
} |
||||
|
||||
// Else, treat as a custom domain |
||||
try { |
||||
const url = new URL(`https://${text}`); |
||||
// Ensure the parsed host matches exactly (case-insensitive already) |
||||
return url.host === lowerText; |
||||
} catch { |
||||
return false; |
||||
} |
||||
} |
||||
</script> |
After Width: | Height: | Size: 927 B |
After Width: | Height: | Size: 927 B |
@ -0,0 +1,65 @@ |
||||
<?php |
||||
|
||||
declare(strict_types=1); |
||||
|
||||
/** |
||||
* SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors |
||||
* SPDX-License-Identifier: AGPL-3.0-or-later |
||||
*/ |
||||
|
||||
namespace OC\Profile\Actions; |
||||
|
||||
use OCP\Accounts\IAccountManager; |
||||
use OCP\IURLGenerator; |
||||
use OCP\IUser; |
||||
use OCP\L10N\IFactory; |
||||
use OCP\Profile\ILinkAction; |
||||
|
||||
class BlueskyAction implements ILinkAction { |
||||
private string $value = ''; |
||||
|
||||
public function __construct( |
||||
private IAccountManager $accountManager, |
||||
private IFactory $l10nFactory, |
||||
private IURLGenerator $urlGenerator, |
||||
) { |
||||
} |
||||
|
||||
public function preload(IUser $targetUser): void { |
||||
$account = $this->accountManager->getAccount($targetUser); |
||||
$this->value = $account->getProperty(IAccountManager::PROPERTY_BLUESKY)->getValue(); |
||||
} |
||||
|
||||
public function getAppId(): string { |
||||
return 'core'; |
||||
} |
||||
|
||||
public function getId(): string { |
||||
return IAccountManager::PROPERTY_BLUESKY; |
||||
} |
||||
|
||||
public function getDisplayId(): string { |
||||
return $this->l10nFactory->get('lib')->t('Bluesky'); |
||||
} |
||||
|
||||
public function getTitle(): string { |
||||
$displayUsername = $this->value; |
||||
return $this->l10nFactory->get('lib')->t('View %s on Bluesky', [$displayUsername]); |
||||
} |
||||
|
||||
public function getPriority(): int { |
||||
return 60; |
||||
} |
||||
|
||||
public function getIcon(): string { |
||||
return $this->urlGenerator->getAbsoluteURL($this->urlGenerator->imagePath('core', 'actions/bluesky.svg')); |
||||
} |
||||
|
||||
public function getTarget(): ?string { |
||||
if (empty($this->value)) { |
||||
return null; |
||||
} |
||||
$username = $this->value; |
||||
return 'https://bsky.app/profile/' . $username; |
||||
} |
||||
} |
Loading…
Reference in new issue