diff options
Diffstat (limited to 'settings/accounts')
| -rw-r--r-- | settings/accounts/accounts.pro | 38 | ||||
| -rw-r--r-- | settings/accounts/providers/fediverse.provider (renamed from settings/accounts/providers/mastodon.provider) | 14 | ||||
| -rw-r--r-- | settings/accounts/services/fediverse-microblog.service (renamed from settings/accounts/services/mastodon-microblog.service) | 12 | ||||
| -rw-r--r-- | settings/accounts/services/fediverse-notifications.service (renamed from settings/accounts/services/mastodon-notifications.service) | 12 | ||||
| -rw-r--r-- | settings/accounts/services/fediverse-sharing.service (renamed from settings/accounts/services/mastodon-sharing.service) | 10 | ||||
| -rw-r--r-- | settings/accounts/ui/FediverseSettingsDisplay.qml (renamed from settings/accounts/ui/MastodonSettingsDisplay.qml) | 45 | ||||
| -rw-r--r-- | settings/accounts/ui/fediverse-settings.qml (renamed from settings/accounts/ui/mastodon-settings.qml) | 14 | ||||
| -rw-r--r-- | settings/accounts/ui/fediverse-update.qml (renamed from settings/accounts/ui/mastodon-update.qml) | 27 | ||||
| -rw-r--r-- | settings/accounts/ui/fediverse.qml (renamed from settings/accounts/ui/mastodon.qml) | 293 |
9 files changed, 334 insertions, 131 deletions
diff --git a/settings/accounts/accounts.pro b/settings/accounts/accounts.pro index 37982a3..1c80cf9 100644 --- a/settings/accounts/accounts.pro +++ b/settings/accounts/accounts.pro @@ -4,8 +4,8 @@ TEMPLATE = aux -TS_FILE = $$OUT_PWD/settings-accounts-mastodon.ts -EE_QM = $$OUT_PWD/settings-accounts-mastodon_eng_en.qm +TS_FILE = $$OUT_PWD/settings-accounts-fediverse.ts +EE_QM = $$OUT_PWD/settings-accounts-fediverse_eng_en.qm ts.commands += lupdate $$PWD/ui -ts $$TS_FILE ts.CONFIG += no_check_exist no_link @@ -30,29 +30,29 @@ QMAKE_EXTRA_TARGETS += ts engineering_english PRE_TARGETDEPS += ts engineering_english OTHER_FILES += \ - $$PWD/providers/mastodon.provider \ - $$PWD/services/mastodon-microblog.service \ - $$PWD/services/mastodon-notifications.service \ - $$PWD/services/mastodon-sharing.service \ - $$PWD/ui/MastodonSettingsDisplay.qml \ - $$PWD/ui/mastodon.qml \ - $$PWD/ui/mastodon-settings.qml \ - $$PWD/ui/mastodon-update.qml - -provider.files += $$PWD/providers/mastodon.provider + $$PWD/providers/fediverse.provider \ + $$PWD/services/fediverse-microblog.service \ + $$PWD/services/fediverse-notifications.service \ + $$PWD/services/fediverse-sharing.service \ + $$PWD/ui/FediverseSettingsDisplay.qml \ + $$PWD/ui/fediverse.qml \ + $$PWD/ui/fediverse-settings.qml \ + $$PWD/ui/fediverse-update.qml + +provider.files += $$PWD/providers/fediverse.provider provider.path = /usr/share/accounts/providers/ services.files += \ - $$PWD/services/mastodon-microblog.service \ - $$PWD/services/mastodon-notifications.service \ - $$PWD/services/mastodon-sharing.service + $$PWD/services/fediverse-microblog.service \ + $$PWD/services/fediverse-notifications.service \ + $$PWD/services/fediverse-sharing.service services.path = /usr/share/accounts/services/ ui.files += \ - $$PWD/ui/MastodonSettingsDisplay.qml \ - $$PWD/ui/mastodon.qml \ - $$PWD/ui/mastodon-settings.qml \ - $$PWD/ui/mastodon-update.qml + $$PWD/ui/FediverseSettingsDisplay.qml \ + $$PWD/ui/fediverse.qml \ + $$PWD/ui/fediverse-settings.qml \ + $$PWD/ui/fediverse-update.qml ui.path = /usr/share/accounts/ui/ INSTALLS += provider services ui ts_install engineering_english_install diff --git a/settings/accounts/providers/mastodon.provider b/settings/accounts/providers/fediverse.provider index 422c231..bb6e329 100644 --- a/settings/accounts/providers/mastodon.provider +++ b/settings/accounts/providers/fediverse.provider @@ -2,11 +2,11 @@ <!-- SPDX-FileCopyrightText: 2013 - 2026 Jolla Ltd. --> <!-- SPDX-License-Identifier: BSD-3-Clause --> <!DOCTYPE provider> -<provider version="1.0" id="mastodon"> - <translations>/usr/share/translations/settings-accounts-mastodon</translations> - <name>Mastodon</name> - <description>Mastodon social network</description> - <icon>image://theme/icon-l-mastodon</icon> +<provider version="1.0" id="fediverse"> + <translations>/usr/share/translations/settings-accounts-fediverse</translations> + <name>Fediverse</name> + <description>Fediverse social network</description> + <icon>image://theme/icon-l-fediverse</icon> <template> <group name="auth"> @@ -25,11 +25,11 @@ </group> </group> <group name="api"> - <setting name="Host">https://mastodon.social</setting> + <setting name="Host">mastodon.social</setting> </group> </template> <tags> - <tag>user-group:account-mastodon</tag> + <tag>user-group:account-fediverse</tag> </tags> </provider> diff --git a/settings/accounts/services/mastodon-microblog.service b/settings/accounts/services/fediverse-microblog.service index 527f70f..9070ec1 100644 --- a/settings/accounts/services/mastodon-microblog.service +++ b/settings/accounts/services/fediverse-microblog.service @@ -1,15 +1,15 @@ <?xml version="1.0" encoding="UTF-8" ?> <!-- SPDX-FileCopyrightText: 2013 - 2026 Jolla Ltd. --> <!-- SPDX-License-Identifier: BSD-3-Clause --> -<service id="mastodon-microblog"> +<service id="fediverse-microblog"> <type>microblogging</type> - <translations>/usr/share/translations/settings-accounts-mastodon</translations> + <translations>/usr/share/translations/settings-accounts-fediverse</translations> <name>Posts</name> - <icon>image://theme/icon-l-mastodon</icon> - <provider>mastodon</provider> + <icon>image://theme/icon-l-fediverse</icon> + <provider>fediverse</provider> <template> - <setting name="sync_profile_templates" type="as">["mastodon.Posts"]</setting> + <setting name="sync_profile_templates" type="as">["fediverse.Posts"]</setting> <group name="auth"> <setting name="method">oauth2</setting> <setting name="mechanism">web_server</setting> @@ -26,7 +26,7 @@ </group> </group> <group name="api"> - <setting name="Host">https://mastodon.social</setting> + <setting name="Host">mastodon.social</setting> </group> </template> </service> diff --git a/settings/accounts/services/mastodon-notifications.service b/settings/accounts/services/fediverse-notifications.service index f5471c9..ea1b59b 100644 --- a/settings/accounts/services/mastodon-notifications.service +++ b/settings/accounts/services/fediverse-notifications.service @@ -1,15 +1,15 @@ <?xml version="1.0" encoding="UTF-8" ?> <!-- SPDX-FileCopyrightText: 2013 - 2026 Jolla Ltd. --> <!-- SPDX-License-Identifier: BSD-3-Clause --> -<service id="mastodon-notifications"> +<service id="fediverse-notifications"> <type>microblogging</type> - <translations>/usr/share/translations/settings-accounts-mastodon</translations> + <translations>/usr/share/translations/settings-accounts-fediverse</translations> <name>Notifications</name> - <icon>image://theme/icon-l-mastodon</icon> - <provider>mastodon</provider> + <icon>image://theme/icon-l-fediverse</icon> + <provider>fediverse</provider> <template> - <setting name="sync_profile_templates" type="as">["mastodon.Notifications"]</setting> + <setting name="sync_profile_templates" type="as">["fediverse.Notifications"]</setting> <group name="auth"> <setting name="method">oauth2</setting> <setting name="mechanism">web_server</setting> @@ -26,7 +26,7 @@ </group> </group> <group name="api"> - <setting name="Host">https://mastodon.social</setting> + <setting name="Host">mastodon.social</setting> </group> </template> </service> diff --git a/settings/accounts/services/mastodon-sharing.service b/settings/accounts/services/fediverse-sharing.service index fdf342a..f66f11b 100644 --- a/settings/accounts/services/mastodon-sharing.service +++ b/settings/accounts/services/fediverse-sharing.service @@ -1,12 +1,12 @@ <?xml version="1.0" encoding="UTF-8" ?> <!-- SPDX-FileCopyrightText: 2013 - 2026 Jolla Ltd. --> <!-- SPDX-License-Identifier: BSD-3-Clause --> -<service id="mastodon-sharing"> +<service id="fediverse-sharing"> <type>sharing</type> - <translations>/usr/share/translations/settings-accounts-mastodon</translations> + <translations>/usr/share/translations/settings-accounts-fediverse</translations> <name>Sharing</name> - <icon>image://theme/icon-l-mastodon</icon> - <provider>mastodon</provider> + <icon>image://theme/icon-l-fediverse</icon> + <provider>fediverse</provider> <template> <group name="auth"> @@ -25,7 +25,7 @@ </group> </group> <group name="api"> - <setting name="Host">https://mastodon.social</setting> + <setting name="Host">mastodon.social</setting> </group> </template> </service> diff --git a/settings/accounts/ui/MastodonSettingsDisplay.qml b/settings/accounts/ui/FediverseSettingsDisplay.qml index 13ac06c..7494460 100644 --- a/settings/accounts/ui/MastodonSettingsDisplay.qml +++ b/settings/accounts/ui/FediverseSettingsDisplay.qml @@ -8,7 +8,7 @@ import QtQuick 2.0 import Sailfish.Silica 1.0 import Sailfish.Accounts 1.0 import com.jolla.settings.accounts 1.0 -import com.jolla.settings.accounts.mastodon 1.0 +import com.jolla.settings.accounts.fediverse 1.0 import org.nemomobile.configuration 1.0 StandardAccountSettingsDisplay { @@ -16,6 +16,10 @@ StandardAccountSettingsDisplay { settingsModified: true property bool postsServiceEnabled: false + property string instanceTitle: { + var value = root.account.configurationValues("")["instance/Title"] + return value ? value.toString().trim() : "" + } function refreshDescriptionEditor() { var description = root.account.configurationValues("")["description"] @@ -38,11 +42,14 @@ StandardAccountSettingsDisplay { } function _providerDisplayName() { + if (instanceTitle.length > 0) { + return instanceTitle + } + var providerDisplayName = root.accountProvider && root.accountProvider.displayName ? root.accountProvider.displayName.toString().trim() : "" - //% "Mastodon" - return providerDisplayName.length > 0 ? providerDisplayName : qsTrId("settings-accounts-mastodon-la-provider_name") + return providerDisplayName.length > 0 ? providerDisplayName : qsTrId("settings-accounts-fediverse-la-provider_name") } onAboutToSaveAccount: { @@ -70,7 +77,7 @@ StandardAccountSettingsDisplay { root.account.setConfigurationValue("", "default_credentials_username", editedDescription) } - // Keep account list title fixed to provider name. + // Keep account list title fixed to the discovered instance title. root.account.displayName = providerDisplayName if (eventsSyncSwitch.checked !== root.account.configurationValues("")["FeedViewAutoSync"]) { @@ -111,23 +118,23 @@ StandardAccountSettingsDisplay { id: syncServicesRepeater TextSwitch { checked: model.enabled - text: model.serviceName === "mastodon-microblog" + text: model.serviceName === "fediverse-microblog" //% "Posts" - ? qsTrId("settings-accounts-mastodon-la-service_posts") - : (model.serviceName === "mastodon-notifications" + ? qsTrId("settings-accounts-fediverse-la-service_posts") + : (model.serviceName === "fediverse-notifications" //% "Notifications" - ? qsTrId("settings-accounts-mastodon-la-service_notifications") + ? qsTrId("settings-accounts-fediverse-la-service_notifications") : model.displayName) - description: model.serviceName === "mastodon-microblog" - //% "Show Mastodon posts in the Events view." - ? qsTrId("settings-accounts-mastodon-la-service_posts_description") - : (model.serviceName === "mastodon-notifications" - //% "Show Mastodon notifications." - ? qsTrId("settings-accounts-mastodon-la-service_notifications_description") + description: model.serviceName === "fediverse-microblog" + //% "Show Fediverse posts in the Events view." + ? qsTrId("settings-accounts-fediverse-la-service_posts_description") + : (model.serviceName === "fediverse-notifications" + //% "Show Fediverse notifications." + ? qsTrId("settings-accounts-fediverse-la-service_notifications_description") : "") visible: text.length > 0 onCheckedChanged: { - if (model.serviceName === "mastodon-microblog") { + if (model.serviceName === "fediverse-microblog") { root.postsServiceEnabled = checked } if (checked) { @@ -142,10 +149,10 @@ StandardAccountSettingsDisplay { TextSwitch { id: eventsSyncSwitch - //% "Sync Mastodon feed automatically" - text: qsTrId("settings-accounts-mastodon-la-auto_sync_feed") - //% "Fetch new posts periodically when browsing Events Mastodon feed." - description: qsTrId("settings-accounts-mastodon-la-auto_sync_feed_description") + //% "Sync Fediverse feed automatically" + text: qsTrId("settings-accounts-fediverse-la-auto_sync_feed") + //% "Fetch new posts periodically when browsing Events Fediverse feed." + description: qsTrId("settings-accounts-fediverse-la-auto_sync_feed_description") enabled: root.postsServiceEnabled onCheckedChanged: { diff --git a/settings/accounts/ui/mastodon-settings.qml b/settings/accounts/ui/fediverse-settings.qml index 0538e44..25e0d99 100644 --- a/settings/accounts/ui/mastodon-settings.qml +++ b/settings/accounts/ui/fediverse-settings.qml @@ -13,11 +13,12 @@ AccountSettingsAgent { id: root property string accountSubtitle: { - var description = account.configurationValues("")["description"] - var detail = description ? description.toString().trim() : "" + var instanceDescription = account.configurationValues("")["instance/Description"] + var detail = instanceDescription ? instanceDescription.toString().trim() : "" if (detail.length > 0) { return detail } + var apiHost = account.configurationValues("")["api/Host"] var host = apiHost ? apiHost.toString().trim() : "" host = host.replace(/^https?:\/\//i, "") @@ -28,6 +29,13 @@ AccountSettingsAgent { if (host.length > 0) { return host } + + var description = account.configurationValues("")["description"] + var handle = description ? description.toString().trim() : "" + if (handle.length > 0) { + return handle + } + var displayName = account.displayName ? account.displayName.toString().trim() : "" if (displayName.length > 0) { return displayName @@ -89,7 +97,7 @@ AccountSettingsAgent { description: root.accountSubtitle } - MastodonSettingsDisplay { + FediverseSettingsDisplay { id: settingsDisplay anchors.top: header.bottom accountManager: root.accountManager diff --git a/settings/accounts/ui/mastodon-update.qml b/settings/accounts/ui/fediverse-update.qml index 2485a83..fe75089 100644 --- a/settings/accounts/ui/mastodon-update.qml +++ b/settings/accounts/ui/fediverse-update.qml @@ -8,7 +8,7 @@ import QtQuick 2.0 import Sailfish.Silica 1.0 import Sailfish.Accounts 1.0 import com.jolla.settings.accounts 1.0 -import com.jolla.settings.accounts.mastodon 1.0 +import com.jolla.settings.accounts.fediverse 1.0 AccountCredentialsAgent { id: root @@ -16,11 +16,12 @@ AccountCredentialsAgent { property bool _started readonly property string callbackUri: "http://ipv4.jolla.com/online/status.html" + readonly property string defaultServerHost: "mastodon.social" function normalizeApiHost(rawHost) { var host = rawHost ? rawHost.trim() : "" if (host.length === 0) { - host = "https://mastodon.social" + host = defaultServerHost } host = host.replace(/^https?:\/\//i, "") @@ -31,7 +32,7 @@ AccountCredentialsAgent { host = host.replace(/\/+$/, "") if (host.length === 0) { - host = "mastodon.social" + host = defaultServerHost } return "https://" + host.toLowerCase() } @@ -68,7 +69,7 @@ AccountCredentialsAgent { return "" } - function _formatMastodonAccountId(accountName, apiHost) { + function _formatFediverseAccountId(accountName, apiHost) { var value = accountName ? accountName.toString().trim() : "" if (value.length === 0) { return "" @@ -99,7 +100,7 @@ AccountCredentialsAgent { return token ? token.toString().trim() : "" } - function _isMastodonAccountId(value) { + function _isFediverseAccountId(value) { var text = value ? value.toString().trim() : "" return /^@[^@]+@[^@]+$/.test(text) } @@ -112,7 +113,7 @@ AccountCredentialsAgent { function _saveDescription(description) { if (description.length > 0) { account.setConfigurationValue("", "description", description) - if (_isMastodonAccountId(description)) { + if (_isFediverseAccountId(description)) { account.setConfigurationValue("", "default_credentials_username", description) } } @@ -121,9 +122,9 @@ AccountCredentialsAgent { } function _updateDescription(responseData) { - var config = account.configurationValues("mastodon-microblog") + var config = account.configurationValues("fediverse-microblog") var apiHost = normalizeApiHost(_valueFromServiceConfig(config, "api/Host")) - var description = _formatMastodonAccountId(_extractAccountName(responseData), apiHost) + var description = _formatFediverseAccountId(_extractAccountName(responseData), apiHost) if (description.length > 0) { _saveDescription(description) return @@ -145,7 +146,7 @@ AccountCredentialsAgent { if (xhr.status >= 200 && xhr.status < 300) { try { var response = JSON.parse(xhr.responseText) - fetchedDescription = _formatMastodonAccountId(_extractAccountName(response), apiHost) + fetchedDescription = _formatFediverseAccountId(_extractAccountName(response), apiHost) } catch (err) { } } @@ -167,7 +168,7 @@ AccountCredentialsAgent { return } - var config = account.configurationValues("mastodon-microblog") + var config = account.configurationValues("fediverse-microblog") var apiHost = normalizeApiHost(_valueFromServiceConfig(config, "api/Host")) var oauthHost = _valueFromServiceConfig(config, "auth/oauth2/web_server/Host") if (oauthHost.length === 0) { @@ -177,8 +178,8 @@ AccountCredentialsAgent { var clientId = _valueFromServiceConfig(config, "auth/oauth2/web_server/ClientId") var clientSecret = _valueFromServiceConfig(config, "auth/oauth2/web_server/ClientSecret") if (clientId.length === 0 || clientSecret.length === 0) { - //% "Missing Mastodon OAuth client credentials" - credentialsUpdateError(qsTrId("settings-accounts-mastodon-la-missing_client_credentials")) + //% "Missing Fediverse OAuth client credentials" + credentialsUpdateError(qsTrId("settings-accounts-fediverse-la-missing_client_credentials")) return } @@ -194,7 +195,7 @@ AccountCredentialsAgent { "Scope": ["read", "write"], "RedirectUri": callbackUri } - initialPage.prepareAccountCredentialsUpdate(account, root.accountProvider, "mastodon-microblog", sessionData) + initialPage.prepareAccountCredentialsUpdate(account, root.accountProvider, "fediverse-microblog", sessionData) } Account { diff --git a/settings/accounts/ui/mastodon.qml b/settings/accounts/ui/fediverse.qml index 129fda5..3f5968a 100644 --- a/settings/accounts/ui/mastodon.qml +++ b/settings/accounts/ui/fediverse.qml @@ -8,7 +8,7 @@ import QtQuick 2.0 import Sailfish.Silica 1.0 import Sailfish.Accounts 1.0 import com.jolla.settings.accounts 1.0 -import com.jolla.settings.accounts.mastodon 1.0 +import com.jolla.settings.accounts.fediverse 1.0 AccountCreationAgent { id: root @@ -18,10 +18,13 @@ AccountCreationAgent { property QtObject _accountSetup property string _pendingApiHost + property var _pendingInstanceContext: ({}) property bool _registering readonly property string callbackUri: "http://ipv4.jolla.com/online/status.html" - readonly property string defaultApiHost: "https://mastodon.social" + readonly property string defaultServerHost: "mastodon.social" + readonly property string defaultApiHost: normalizeApiHost(defaultServerHost) + readonly property string genericIconPath: "image://theme/icon-l-fediverse" function normalizeApiHost(rawHost) { var host = rawHost ? rawHost.trim() : "" @@ -46,6 +49,27 @@ AccountCreationAgent { return apiHost.replace(/^https?:\/\//i, "") } + function _trimmedString(value) { + return value ? value.toString().trim() : "" + } + + function _normalizeResourceUrl(rawUrl, apiHost) { + var value = _trimmedString(rawUrl) + if (value.length === 0) { + return "" + } + if (/^https?:\/\//i.test(value)) { + return value + } + if (value.indexOf("//") === 0) { + return "https:" + value + } + if (value.charAt(0) === "/") { + return apiHost + value + } + return apiHost + "/" + value.replace(/^\/+/, "") + } + function _displayName(apiHost) { return oauthHost(apiHost) } @@ -58,6 +82,78 @@ AccountCreationAgent { return _displayName(defaultApiHost) } + function _instanceContext(apiHost) { + var normalizedApiHost = normalizeApiHost(apiHost) + var title = _fallbackDisplayName(normalizedApiHost) + return { + "apiHost": normalizedApiHost, + "oauthHost": oauthHost(normalizedApiHost), + "instanceTitle": title.length > 0 ? title : qsTrId("settings-accounts-fediverse-la-provider_name"), + "instanceDescription": "", + "instanceIconUrl": "", + "instanceIconPath": instanceIconCache.cachedIconPath(normalizedApiHost) + } + } + + function _extractInstanceTitle(responseData, apiHost) { + var candidates = [ + responseData ? responseData.title : "", + responseData ? responseData.name : "", + responseData ? responseData.uri : "" + ] + for (var i = 0; i < candidates.length; ++i) { + var value = _trimmedString(candidates[i]) + if (value.length > 0) { + return value + } + } + return _fallbackDisplayName(apiHost) + } + + function _extractInstanceDescription(responseData) { + var candidates = [ + responseData ? responseData.short_description : "", + responseData ? responseData.description : "", + responseData ? responseData.shortDescription : "" + ] + for (var i = 0; i < candidates.length; ++i) { + var value = _trimmedString(candidates[i]) + if (value.length > 0) { + return value + } + } + return "" + } + + function _extractInstanceIconUrl(responseData, apiHost) { + if (!responseData) { + return "" + } + + if (responseData.thumbnail) { + if (typeof responseData.thumbnail === "string") { + return _normalizeResourceUrl(responseData.thumbnail, apiHost) + } + if (responseData.thumbnail.url) { + return _normalizeResourceUrl(responseData.thumbnail.url, apiHost) + } + if (responseData.thumbnail.static_url) { + return _normalizeResourceUrl(responseData.thumbnail.static_url, apiHost) + } + } + + if (responseData.icon) { + if (typeof responseData.icon === "string") { + return _normalizeResourceUrl(responseData.icon, apiHost) + } + if (responseData.icon.url) { + return _normalizeResourceUrl(responseData.icon.url, apiHost) + } + } + + return "" + } + function _showRegistrationError(message, busyPage) { _registering = false accountCreationError(message) @@ -79,12 +175,16 @@ AccountCreationAgent { pageStack.replace(_oauthPage) } - function _registerClientApplication(apiHost, busyPage) { + function _registerClientApplication(context, busyPage) { if (_registering) { return } _registering = true + if (context.instanceIconUrl.length > 0 && context.instanceIconPath.length === 0) { + instanceIconCache.cacheIcon(context.apiHost, context.instanceIconUrl) + } + var xhr = new XMLHttpRequest() xhr.onreadystatechange = function() { if (xhr.readyState !== XMLHttpRequest.DONE) { @@ -92,8 +192,7 @@ AccountCreationAgent { } if (xhr.status < 200 || xhr.status >= 300) { - //% "Failed to register Mastodon app for %1" - _showRegistrationError(qsTrId("settings-accounts-mastodon-la-register_app_failed").arg(apiHost), busyPage) + _showRegistrationError(qsTrId("settings-accounts-fediverse-la-register_app_failed").arg(context.apiHost), busyPage) return } @@ -101,37 +200,80 @@ AccountCreationAgent { try { response = JSON.parse(xhr.responseText) } catch (err) { - //% "Invalid Mastodon app registration response" - _showRegistrationError(qsTrId("settings-accounts-mastodon-la-invalid_app_registration_response"), busyPage) + _showRegistrationError(qsTrId("settings-accounts-fediverse-la-invalid_app_registration_response"), busyPage) return } if (!response.client_id || !response.client_secret) { - //% "Mastodon app registration did not return credentials" - _showRegistrationError(qsTrId("settings-accounts-mastodon-la-app_registration_missing_credentials"), busyPage) + _showRegistrationError(qsTrId("settings-accounts-fediverse-la-app_registration_missing_credentials"), busyPage) return } - _showOAuthPage({ - "apiHost": apiHost, - "oauthHost": oauthHost(apiHost), - "clientId": response.client_id, - "clientSecret": response.client_secret - }) + context.clientId = response.client_id + context.clientSecret = response.client_secret + _showOAuthPage(context) } var postData = [] - //% "Mastodon in SailfishOS" - postData.push("client_name=" + encodeURIComponent(qsTrId("settings-accounts-mastodon-la-client_name"))) + postData.push("client_name=" + encodeURIComponent(qsTrId("settings-accounts-fediverse-la-client_name"))) postData.push("redirect_uris=" + encodeURIComponent(callbackUri)) postData.push("scopes=" + encodeURIComponent("read write")) postData.push("website=" + encodeURIComponent("https://sailfishos.org")) - xhr.open("POST", apiHost + "/api/v1/apps") + xhr.open("POST", context.apiHost + "/api/v1/apps") xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded") xhr.send(postData.join("&")) } + function _discoverInstanceContext(apiHost, busyPage) { + var context = _instanceContext(apiHost) + _pendingInstanceContext = context + + function continueWithContext() { + _pendingInstanceContext = context + _registerClientApplication(context, busyPage) + } + + function loadEndpoint(paths, index) { + if (index >= paths.length) { + continueWithContext() + return + } + + var xhr = new XMLHttpRequest() + xhr.onreadystatechange = function() { + if (xhr.readyState !== XMLHttpRequest.DONE) { + return + } + + if (xhr.status >= 200 && xhr.status < 300) { + try { + var response = JSON.parse(xhr.responseText) + context.instanceTitle = _extractInstanceTitle(response, context.apiHost) + context.instanceDescription = _extractInstanceDescription(response) + context.instanceIconUrl = _extractInstanceIconUrl(response, context.apiHost) + if (context.instanceIconUrl.length > 0) { + var cachedPath = instanceIconCache.cachedIconPath(context.apiHost) + if (cachedPath.length > 0) { + context.instanceIconPath = cachedPath + } + } + } catch (err) { + } + continueWithContext() + return + } + + loadEndpoint(paths, index + 1) + } + + xhr.open("GET", context.apiHost + paths[index]) + xhr.send() + } + + loadEndpoint(["/api/v2/instance", "/api/v1/instance"], 0) + } + function _extractAccountName(responseData) { if (!responseData) { return "" @@ -160,7 +302,7 @@ AccountCreationAgent { return "" } - function _formatMastodonAccountId(accountName, apiHost) { + function _formatFediverseAccountId(accountName, apiHost) { var value = accountName ? accountName.toString().trim() : "" if (value.length === 0) { return "" @@ -179,7 +321,7 @@ AccountCreationAgent { return "@" + value + "@" + host } - function _isMastodonAccountId(value) { + function _isFediverseAccountId(value) { var text = value ? value.toString().trim() : "" return /^@[^@]+@[^@]+$/.test(text) } @@ -204,7 +346,11 @@ AccountCreationAgent { "clientId": context.clientId, "clientSecret": context.clientSecret, "accessToken": _extractAccessToken(responseData), - "accountDescription": _formatMastodonAccountId(_extractAccountName(responseData), context.apiHost) + "accountDescription": _formatFediverseAccountId(_extractAccountName(responseData), context.apiHost), + "instanceTitle": context.instanceTitle, + "instanceDescription": context.instanceDescription, + "instanceIconUrl": context.instanceIconUrl, + "instanceIconPath": context.instanceIconPath } _accountSetup = accountSetupComponent.createObject(root, props) _accountSetup.done.connect(function() { @@ -212,8 +358,7 @@ AccountCreationAgent { _goToSettings(accountId) }) _accountSetup.error.connect(function() { - //% "Failed to finish Mastodon account setup" - accountCreationError(qsTrId("settings-accounts-mastodon-la-account_setup_failed")) + accountCreationError(qsTrId("settings-accounts-fediverse-la-account_setup_failed")) }) } @@ -225,6 +370,20 @@ AccountCreationAgent { pageStack.replace(_settingsDialog) } + FediverseInstanceIconCache { + id: instanceIconCache + + onIconReady: { + var normalizedHost = root.normalizeApiHost(apiHost) + if (root._pendingInstanceContext.apiHost === normalizedHost) { + root._pendingInstanceContext.instanceIconPath = iconPath + } + if (root._accountSetup && root._accountSetup.apiHost === normalizedHost) { + root._accountSetup.updateInstanceIcon(iconPath) + } + } + } + initialPage: Dialog { id: setupDialog @@ -240,7 +399,6 @@ AccountCreationAgent { DialogHeader { id: header - //% "Sign in" acceptText: qsTrId("settings-accounts-common-bt-sign_in") } @@ -259,19 +417,17 @@ AccountCreationAgent { id: promptIcon width: Theme.iconSizeMedium height: Theme.iconSizeMedium - source: "image://theme/icon-l-mastodon" + source: root.genericIconPath fillMode: Image.PreserveAspectFit sourceSize.width: width sourceSize.height: height } - //: Prompt shown in account setup before OAuth sign-in. Label { width: parent.width - promptIcon.width - parent.spacing wrapMode: Text.Wrap color: Theme.highlightColor - //% "Enter your Mastodon server, then sign in." - text: qsTrId("settings-accounts-mastodon-la-enter_server_then_sign_in") + text: qsTrId("settings-accounts-fediverse-la-enter_server_then_sign_in") } } @@ -279,9 +435,8 @@ AccountCreationAgent { id: instanceField x: Theme.horizontalPageMargin width: parent.width - x * 2 - //% "Server" - label: qsTrId("settings-accounts-mastodon-la-server") - placeholderText: "mastodon.social" + label: qsTrId("settings-accounts-fediverse-la-server") + placeholderText: root.defaultServerHost inputMethodHints: Qt.ImhNoAutoUppercase | Qt.ImhUrlCharactersOnly EnterKey.iconSource: "image://theme/icon-m-enter-next" EnterKey.onClicked: { @@ -296,11 +451,10 @@ AccountCreationAgent { Component { id: busyComponent AccountBusyPage { - //% "Preparing Mastodon sign-in..." - busyDescription: qsTrId("settings-accounts-mastodon-la-preparing_sign_in") + busyDescription: qsTrId("settings-accounts-fediverse-la-preparing_sign_in") onStatusChanged: { if (status === PageStatus.Active && root._pendingApiHost.length > 0) { - root._registerClientApplication(root._pendingApiHost, this) + root._discoverInstanceContext(root._pendingApiHost, this) } } } @@ -322,7 +476,7 @@ AccountCreationAgent { "Scope": ["read", "write"], "RedirectUri": root.callbackUri } - prepareAccountCreation(root.accountProvider, "mastodon-microblog", sessionData) + prepareAccountCreation(root.accountProvider, "fediverse-microblog", sessionData) } onAccountCreated: { @@ -347,6 +501,10 @@ AccountCreationAgent { property string clientSecret property string accessToken property string accountDescription + property string instanceTitle + property string instanceDescription + property string instanceIconUrl + property string instanceIconPath property bool hasConfigured signal done() @@ -368,31 +526,57 @@ AccountCreationAgent { } } + function _serviceNames() { + return ["fediverse-microblog", "fediverse-notifications", "fediverse-sharing"] + } + + function _effectiveInstanceTitle() { + var title = root._trimmedString(instanceTitle) + return title.length > 0 ? title : qsTrId("settings-accounts-fediverse-la-provider_name") + } + + function _effectiveIconPath() { + return root._trimmedString(instanceIconPath).length > 0 ? instanceIconPath : root.genericIconPath + } + + function _applyIconPath(iconPath) { + instanceIconPath = iconPath + newAccount.setConfigurationValue("", "iconPath", _effectiveIconPath()) + var services = _serviceNames() + for (var i = 0; i < services.length; ++i) { + newAccount.setConfigurationValue(services[i], "iconPath", _effectiveIconPath()) + } + if (hasConfigured) { + newAccount.sync() + } + } + + function updateInstanceIcon(iconPath) { + if (root._trimmedString(iconPath).length === 0) { + return + } + _applyIconPath(iconPath) + } + function configure() { hasConfigured = true - var services = ["mastodon-microblog", "mastodon-notifications", "mastodon-sharing"] - var providerDisplayName = root.accountProvider && root.accountProvider.displayName - ? root.accountProvider.displayName.toString().trim() - : "" - if (providerDisplayName.length === 0) { - //% "Mastodon" - providerDisplayName = qsTrId("settings-accounts-mastodon-la-provider_name") - } + var services = _serviceNames() + var providerDisplayName = _effectiveInstanceTitle() newAccount.displayName = providerDisplayName newAccount.setConfigurationValue("", "api/Host", apiHost) newAccount.setConfigurationValue("", "FeedViewAutoSync", true) + newAccount.setConfigurationValue("", "instance/Title", providerDisplayName) + newAccount.setConfigurationValue("", "instance/Description", root._trimmedString(instanceDescription)) + newAccount.setConfigurationValue("", "instance/IconUrl", root._trimmedString(instanceIconUrl)) + _applyIconPath(_effectiveIconPath()) + if (accountDescription.length > 0) { newAccount.setConfigurationValue("", "description", accountDescription) - if (root._isMastodonAccountId(accountDescription)) { + if (root._isFediverseAccountId(accountDescription)) { newAccount.setConfigurationValue("", "default_credentials_username", accountDescription) } - } else { - var hostDisplayName = root._fallbackDisplayName(apiHost) - if (hostDisplayName.length > 0) { - newAccount.setConfigurationValue("", "description", hostDisplayName) - } } for (var i = 0; i < services.length; ++i) { @@ -412,6 +596,10 @@ AccountCreationAgent { newAccount.enableWithService(services[j]) } + if (instanceIconUrl.length > 0 && instanceIconPath.length === 0) { + instanceIconCache.cacheIcon(apiHost, instanceIconUrl) + } + if (accountDescription.length > 0 || accessToken.length === 0) { newAccount.sync() return @@ -426,11 +614,11 @@ AccountCreationAgent { if (xhr.status >= 200 && xhr.status < 300) { try { var response = JSON.parse(xhr.responseText) - var fetchedDescription = root._formatMastodonAccountId(root._extractAccountName(response), apiHost) + var fetchedDescription = root._formatFediverseAccountId(root._extractAccountName(response), apiHost) if (fetchedDescription.length > 0) { accountDescription = fetchedDescription newAccount.setConfigurationValue("", "description", fetchedDescription) - if (root._isMastodonAccountId(fetchedDescription)) { + if (root._isFediverseAccountId(fetchedDescription)) { newAccount.setConfigurationValue("", "default_credentials_username", fetchedDescription) } } @@ -472,7 +660,7 @@ AccountCreationAgent { id: header } - MastodonSettingsDisplay { + FediverseSettingsDisplay { id: settingsDisplay anchors.top: header.bottom accountManager: root.accountManager @@ -488,5 +676,4 @@ AccountCreationAgent { } } } - } |
