From 5f7233fd20b85560ce903f7f26df405daf0414e2 Mon Sep 17 00:00:00 2001
From: Michael <heluecht@pirati.ca>
Date: Wed, 28 Feb 2024 03:05:57 +0000
Subject: [PATCH] Bluesky: Enabled support for Friendica handles

---
 bluesky/bluesky.php                      | 56 +++++++++++++-----
 bluesky/lang/C/messages.po               | 73 +++++++++++++++++-------
 bluesky/templates/admin.tpl              |  2 +
 bluesky/templates/connector_settings.tpl |  1 +
 4 files changed, 96 insertions(+), 36 deletions(-)
 create mode 100644 bluesky/templates/admin.tpl

diff --git a/bluesky/bluesky.php b/bluesky/bluesky.php
index db60d1a4d..5fc0a4f0a 100644
--- a/bluesky/bluesky.php
+++ b/bluesky/bluesky.php
@@ -42,6 +42,7 @@ use Friendica\Model\ItemURI;
 use Friendica\Model\Photo;
 use Friendica\Model\Post;
 use Friendica\Model\Tag;
+use Friendica\Model\User;
 use Friendica\Network\HTTPClient\Client\HttpClientAccept;
 use Friendica\Network\HTTPClient\Client\HttpClientOptions;
 use Friendica\Object\Image;
@@ -316,20 +317,44 @@ function bluesky_unblock(array &$hook_data)
 	$hook_data['result'] = true;
 }
 
+function bluesky_addon_admin(string &$o)
+{
+	$t = Renderer::getMarkupTemplate('admin.tpl', 'addon/bluesky/');
+
+	$o = Renderer::replaceMacros($t, [
+		'$submit' => DI::l10n()->t('Save Settings'),
+		'$friendica_handles'    => ['friendica_handles', DI::l10n()->t('Allow your users to use your hostname for their Bluesky handles'), DI::config()->get('bluesky', 'friendica_handles'), DI::l10n()->t('Before enabling this option, you have to download and configure the bluesky-handles repository on your system. See https://git.friendi.ca/heluecht/bluesky-handles')],
+	]);
+}
+
+function bluesky_addon_admin_post()
+{
+	DI::config()->set('bluesky', 'friendica_handles', (bool)$_POST['friendica_handles']);
+}
+
 function bluesky_settings(array &$data)
 {
 	if (!DI::userSession()->getLocalUserId()) {
 		return;
 	}
 
-	$enabled      = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'post') ?? false;
-	$def_enabled  = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'post_by_default') ?? false;
-	$pds          = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'pds');
-	$handle       = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'handle');
-	$did          = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'did');
-	$token        = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'access_token');
-	$import       = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'import') ?? false;
-	$import_feeds = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'import_feeds') ?? false;
+	$enabled       = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'post') ?? false;
+	$def_enabled   = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'post_by_default') ?? false;
+	$pds           = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'pds');
+	$handle        = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'handle');
+	$did           = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'did');
+	$token         = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'access_token');
+	$import        = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'import') ?? false;
+	$import_feeds  = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'import_feeds') ?? false;
+	$custom_handle = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'friendica_handle') ?? false;
+
+	if (DI::config()->get('bluesky', 'friendica_handles')) {
+		$self = User::getById(DI::userSession()->getLocalUserId(), ['nickname']);
+		$handle = $self['nickname'] . '.' . DI::baseUrl()->getHost();
+		$friendica_handle = ['bluesky_friendica_handle', DI::l10n()->t('Allow to use %s as your Bluesky handle.', $handle), $custom_handle, DI::l10n()->t('When enabled, you can use %s as your Bluesky handle. After you enabled this option, please go to https://bsky.app/settings and select to change your handle. Select that you have got your own domain. Then enter %s and select "No DNS Panel". Then select "Verify Text File".', $handle, $handle)];
+	} else {
+		$friendica_handle = [];
+	}
 
 	$t    = Renderer::getMarkupTemplate('connector_settings.tpl', 'addon/bluesky/');
 	$html = Renderer::replaceMacros($t, [
@@ -337,6 +362,7 @@ function bluesky_settings(array &$data)
 		'$bydefault'    => ['bluesky_bydefault', DI::l10n()->t('Post to Bluesky by default'), $def_enabled],
 		'$import'       => ['bluesky_import', DI::l10n()->t('Import the remote timeline'), $import],
 		'$import_feeds' => ['bluesky_import_feeds', DI::l10n()->t('Import the pinned feeds'), $import_feeds, DI::l10n()->t('When activated, Posts will be imported from all the feeds that you pinned in Bluesky.')],
+		'$custom_handle' => $friendica_handle,
 		'$pds'          => ['bluesky_pds', DI::l10n()->t('Personal Data Server'), $pds, DI::l10n()->t('The personal data server (PDS) is the system that hosts your profile.'), '', 'readonly'],
 		'$handle'       => ['bluesky_handle', DI::l10n()->t('Bluesky handle'), $handle],
 		'$did'          => ['bluesky_did', DI::l10n()->t('Bluesky DID'), $did, DI::l10n()->t('This is the unique identifier. It will be fetched automatically, when the handle is entered.'), '', 'readonly'],
@@ -404,11 +430,12 @@ function bluesky_settings_post(array &$b)
 
 	$handle = trim($_POST['bluesky_handle'], ' @');
 
-	DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'bluesky', 'post',            intval($_POST['bluesky']));
-	DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'bluesky', 'post_by_default', intval($_POST['bluesky_bydefault']));
-	DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'bluesky', 'handle',          $handle);
-	DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'bluesky', 'import',          intval($_POST['bluesky_import']));
-	DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'bluesky', 'import_feeds',    intval($_POST['bluesky_import_feeds']));
+	DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'bluesky', 'post',             intval($_POST['bluesky']));
+	DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'bluesky', 'post_by_default',  intval($_POST['bluesky_bydefault']));
+	DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'bluesky', 'handle',           $handle);
+	DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'bluesky', 'import',           intval($_POST['bluesky_import']));
+	DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'bluesky', 'import_feeds',     intval($_POST['bluesky_import_feeds']));
+	DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'bluesky', 'friendica_handle', intval($_POST['bluesky_friendica_handle']));
 
 	if (!empty($handle)) {
 		if (empty($old_did) || $old_handle != $handle) {
@@ -1533,6 +1560,7 @@ function bluesky_get_contact(stdClass $author, int $uid, int $fetch_uid): array
 function bluesky_get_contact_fields(stdClass $author, int $uid, int $fetch_uid, bool $update): array
 {
 	$nick = $author->handle ?? $author->did;
+	$name = $author->displayName ?? $nick;
 	$fields = [
 		'uid'      => $uid,
 		'network'  => Protocol::BLUESKY,
@@ -1544,7 +1572,7 @@ function bluesky_get_contact_fields(stdClass $author, int $uid, int $fetch_uid,
 		'url'      => $author->did,
 		'nurl'     => $author->did,
 		'alias'    => BLUESKY_WEB . '/profile/' . $nick,
-		'name'     => $author->displayName ?? $nick,
+		'name'     => $name ?: $nick,
 		'nick'     => $nick,
 		'addr'     => $nick,
 	];
diff --git a/bluesky/lang/C/messages.po b/bluesky/lang/C/messages.po
index 132e608a1..0d69cc102 100644
--- a/bluesky/lang/C/messages.po
+++ b/bluesky/lang/C/messages.po
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: \n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2023-12-06 06:30+0000\n"
+"POT-Creation-Date: 2024-02-28 03:05+0000\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -17,100 +17,129 @@ msgstr ""
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 
-#: bluesky.php:336
+#: bluesky.php:325
+msgid "Save Settings"
+msgstr ""
+
+#: bluesky.php:326
+msgid "Allow your users to use your hostname for their Bluesky handles"
+msgstr ""
+
+#: bluesky.php:326
+msgid ""
+"Before enabling this option, you have to download and configure the bluesky-"
+"handles repository on your system. See https://git.friendi.ca/heluecht/"
+"bluesky-handles"
+msgstr ""
+
+#: bluesky.php:354
+#, php-format
+msgid "Allow to use %s as your Bluesky handle."
+msgstr ""
+
+#: bluesky.php:354
+#, php-format
+msgid ""
+"When enabled, you can use %s as your Bluesky handle. After you enabled this "
+"option, please go to https://bsky.app/settings and select to change your "
+"handle. Select that you have got your own domain. Then enter %s and select "
+"\"No DNS Panel\". Then select \"Verify Text File\"."
+msgstr ""
+
+#: bluesky.php:361
 msgid "Enable Bluesky Post Addon"
 msgstr ""
 
-#: bluesky.php:337
+#: bluesky.php:362
 msgid "Post to Bluesky by default"
 msgstr ""
 
-#: bluesky.php:338
+#: bluesky.php:363
 msgid "Import the remote timeline"
 msgstr ""
 
-#: bluesky.php:339
+#: bluesky.php:364
 msgid "Import the pinned feeds"
 msgstr ""
 
-#: bluesky.php:339
+#: bluesky.php:364
 msgid ""
 "When activated, Posts will be imported from all the feeds that you pinned in "
 "Bluesky."
 msgstr ""
 
-#: bluesky.php:340
+#: bluesky.php:366
 msgid "Personal Data Server"
 msgstr ""
 
-#: bluesky.php:340
+#: bluesky.php:366
 msgid "The personal data server (PDS) is the system that hosts your profile."
 msgstr ""
 
-#: bluesky.php:341
+#: bluesky.php:367
 msgid "Bluesky handle"
 msgstr ""
 
-#: bluesky.php:342
+#: bluesky.php:368
 msgid "Bluesky DID"
 msgstr ""
 
-#: bluesky.php:342
+#: bluesky.php:368
 msgid ""
 "This is the unique identifier. It will be fetched automatically, when the "
 "handle is entered."
 msgstr ""
 
-#: bluesky.php:343
+#: bluesky.php:369
 msgid "Bluesky app password"
 msgstr ""
 
-#: bluesky.php:343
+#: bluesky.php:369
 msgid ""
 "Please don't add your real password here, but instead create a specific app "
 "password in the Bluesky settings."
 msgstr ""
 
-#: bluesky.php:349
+#: bluesky.php:375
 msgid "Bluesky Import/Export"
 msgstr ""
 
-#: bluesky.php:359
+#: bluesky.php:385
 msgid ""
 "You are not authenticated. Please enter your handle and the app password."
 msgstr ""
 
-#: bluesky.php:379
+#: bluesky.php:405
 msgid ""
 "You are authenticated to Bluesky. For security reasons the password isn't "
 "stored."
 msgstr ""
 
-#: bluesky.php:381
+#: bluesky.php:407
 msgid ""
 "The communication with the personal data server service (PDS) is established."
 msgstr ""
 
-#: bluesky.php:383
+#: bluesky.php:409
 msgid "Communication issues with the personal data server service (PDS)."
 msgstr ""
 
-#: bluesky.php:385
+#: bluesky.php:411
 msgid ""
 "The DID for the provided handle could not be detected. Please check if you "
 "entered the correct handle."
 msgstr ""
 
-#: bluesky.php:387
+#: bluesky.php:413
 msgid "The personal data server service (PDS) could not be detected."
 msgstr ""
 
-#: bluesky.php:389
+#: bluesky.php:415
 msgid ""
 "The authentication with the provided handle and password failed. Please "
 "check if you entered the correct password."
 msgstr ""
 
-#: bluesky.php:457
+#: bluesky.php:484
 msgid "Post to Bluesky"
 msgstr ""
diff --git a/bluesky/templates/admin.tpl b/bluesky/templates/admin.tpl
new file mode 100644
index 000000000..7b752a882
--- /dev/null
+++ b/bluesky/templates/admin.tpl
@@ -0,0 +1,2 @@
+{{include file="field_checkbox.tpl" field=$friendica_handles}}
+<div class="submit"><input type="submit" name="page_site" value="{{$submit}}" /></div>
diff --git a/bluesky/templates/connector_settings.tpl b/bluesky/templates/connector_settings.tpl
index db5ac5d5b..f50e9cc61 100644
--- a/bluesky/templates/connector_settings.tpl
+++ b/bluesky/templates/connector_settings.tpl
@@ -3,6 +3,7 @@
 {{include file="field_checkbox.tpl" field=$bydefault}}
 {{include file="field_checkbox.tpl" field=$import}}
 {{include file="field_checkbox.tpl" field=$import_feeds}}
+{{include file="field_checkbox.tpl" field=$custom_handle}}
 {{include file="field_input.tpl" field=$pds}}
 {{include file="field_input.tpl" field=$handle}}
 {{include file="field_input.tpl" field=$did}}