From 5d501d6018f5baa7d2a43872bac444ed13ddfa2e Mon Sep 17 00:00:00 2001 From: KotlinGeekDev Date: Thu, 2 Jan 2025 14:13:46 +0100 Subject: [PATCH] Apply suggested fixes. --- .../nononsenseapps/feeder/model/FeedParser.kt | 22 ++++++---- .../feeder/model/RssLocalSync.kt | 9 ++++- .../feeder/model/opml/OPMLImporter.kt | 15 +------ .../feeder/model/opml/OpmlPullParser.kt | 3 +- .../com/nononsenseapps/feeder/ui/Constants.kt | 2 + .../editfeed/CreateFeedScreenViewModel.kt | 11 +++-- .../ui/compose/editfeed/EditFeedScreen.kt | 15 ++++--- .../editfeed/EditFeedScreenViewModel.kt | 21 +++++----- .../ui/compose/searchfeed/SearchFeedScreen.kt | 40 +++++++++---------- .../compose/searchfeed/SearchFeedViewModel.kt | 18 ++------- .../ui/compose/settings/OpenAISection.kt | 2 +- .../nononsenseapps/feeder/util/LinkUtils.kt | 8 ++-- 12 files changed, 78 insertions(+), 88 deletions(-) diff --git a/app/src/main/java/com/nononsenseapps/feeder/model/FeedParser.kt b/app/src/main/java/com/nononsenseapps/feeder/model/FeedParser.kt index ae5b9ca6a0..c7fe55acde 100644 --- a/app/src/main/java/com/nononsenseapps/feeder/model/FeedParser.kt +++ b/app/src/main/java/com/nononsenseapps/feeder/model/FeedParser.kt @@ -247,7 +247,7 @@ class FeedParser(override val di: DI) : DIAware { when (parsedProfile) { is Nip21Enum.Pubkey -> return Nip19Profile(parsedProfile.publicKey) is Nip21Enum.Profile -> return Nip19Profile(parsedProfile.profile.publicKey(), parsedProfile.profile.relays()) - else -> throw Throwable(message = "Could not find the user's info: $nostrUri") + else -> throw NostrUriParserException(message = "Could not find the user's info: $nostrUri") } } } @@ -264,7 +264,7 @@ class FeedParser(override val di: DI) : DIAware { it.size < 4 }.orEmpty() .ifEmpty { getUserPublishRelays(publicKey) } - println("Relays from Nip19 -> ${relayList.joinToString(separator = ", ")}") + logDebug(LOG_TAG, "Relays from Nip19 -> ${relayList.joinToString(separator = ", ")}") relayList .ifEmpty { defaultFetchRelays } .forEach { relayUrl -> @@ -276,7 +276,7 @@ class FeedParser(override val di: DI) : DIAware { publicKey = publicKey, timeout = Duration.ofSeconds(5L), ) - println(profileInfo.asPrettyJson()) + logDebug(LOG_TAG, profileInfo.asPrettyJson()) // Check if all relays in relaylist can be connected to AuthorNostrData( @@ -329,7 +329,7 @@ class FeedParser(override val di: DI) : DIAware { Filter() .author(author) .kind(Kind.fromEnum(KindEnum.LongFormTextNote)) - logDebug(LOG_TAG, "Relay List size: -> ${relays.size}") + logDebug(LOG_TAG, "Relay List size: ${relays.size}") nostrClient.removeAllRelays() val relaysToUse = @@ -337,7 +337,7 @@ class FeedParser(override val di: DI) : DIAware { .ifEmpty { defaultFetchRelays } relaysToUse.forEach { relay -> nostrClient.addReadRelay(relay) } nostrClient.connect() - logDebug(LOG_TAG, "-------------------FETCHING ARTICLES----------------------") + logDebug(LOG_TAG, "FETCHING ARTICLES") val articleEventSet = nostrClient.fetchEventsFrom( urls = relaysToUse, @@ -448,7 +448,7 @@ private fun List.mapToFeed( authorName: String, imageUrl: String, ): ParsedFeed { - val description = "Nostr articles by $authorName" + val description = "Nostr: $authorName" val author = ParsedAuthor( name = authorName, @@ -511,14 +511,14 @@ fun Event.asArticle( val articleSummary = tags().find(TagKind.Summary)?.content() val articleContent = content() val parsedMarkdown = markDownParser.buildMarkdownTreeFromString(articleContent) - val htmlFromContent = HtmlGenerator(articleContent, parsedMarkdown, CommonMarkFlavourDescriptor()).generateHtml() + val htmlContent = HtmlGenerator(articleContent, parsedMarkdown, CommonMarkFlavourDescriptor()).generateHtml() return ParsedArticle( id = articleId, url = articleUri, external_url = externalLink, title = articleTitle, - content_html = htmlFromContent, + content_html = htmlContent, content_text = articleContent, summary = articleSummary, image = if (articleImage != null) MediaImage(url = articleImage.toString()) else null, @@ -733,6 +733,12 @@ class AuthorNostrData( val relayList: List, ) +sealed class NostrException(message: String) : Exception(message) + +class NostrUriParserException(override val message: String) : NostrException(message) + +class NostrMetadataException(override val message: String) : NostrException(message) + @Parcelize sealed class FeedParserError : Parcelable { abstract val url: String diff --git a/app/src/main/java/com/nononsenseapps/feeder/model/RssLocalSync.kt b/app/src/main/java/com/nononsenseapps/feeder/model/RssLocalSync.kt index 04d8d7048b..56e37d6edf 100644 --- a/app/src/main/java/com/nononsenseapps/feeder/model/RssLocalSync.kt +++ b/app/src/main/java/com/nononsenseapps/feeder/model/RssLocalSync.kt @@ -1,6 +1,8 @@ package com.nononsenseapps.feeder.model import android.util.Log +import com.nononsenseapps.feeder.FeederApplication +import com.nononsenseapps.feeder.R import com.nononsenseapps.feeder.archmodel.Repository import com.nononsenseapps.feeder.background.runOnceFullTextSync import com.nononsenseapps.feeder.blob.blobFile @@ -50,6 +52,7 @@ class RssLocalSync(override val di: DI) : DIAware { private val feedParser: FeedParser by instance() private val okHttpClient: OkHttpClient by instance() private val filePathProvider: FilePathProvider by instance() + private val application: FeederApplication by instance() suspend fun syncFeeds( feedId: Long = ID_UNSET, @@ -249,10 +252,12 @@ class RssLocalSync(override val di: DI) : DIAware { Either.catching( onCatch = { t -> FetchError(url = url.toString(), throwable = t) }, ) { - feedParser.getProfileMetadata(url) - .getOrNull()!! + feedParser.getProfileMetadata(url).getOrNull() ?: throw NostrMetadataException("Could not find metadata for $url") }.flatMap { profile -> feedParser.findNostrFeed(profile) + .map { + it.copy(description = application.applicationContext.getString(R.string.nostr_feed_description, profile.name)) + } } } else { Either.catching( diff --git a/app/src/main/java/com/nononsenseapps/feeder/model/opml/OPMLImporter.kt b/app/src/main/java/com/nononsenseapps/feeder/model/opml/OPMLImporter.kt index c6c9168758..b88ee100a0 100644 --- a/app/src/main/java/com/nononsenseapps/feeder/model/opml/OPMLImporter.kt +++ b/app/src/main/java/com/nononsenseapps/feeder/model/opml/OPMLImporter.kt @@ -14,8 +14,6 @@ import com.nononsenseapps.feeder.archmodel.themeOptionsFromString import com.nononsenseapps.feeder.db.room.Feed import com.nononsenseapps.feeder.db.room.FeedDao import com.nononsenseapps.feeder.model.OPMLParserHandler -import com.nononsenseapps.feeder.util.isAdaptedUrlFromNostrUri -import com.nononsenseapps.feeder.util.logDebug import kotlinx.coroutines.flow.first import org.kodein.di.DI import org.kodein.di.DIAware @@ -27,22 +25,11 @@ open class OPMLImporter(override val di: DI) : OPMLParserHandler, DIAware { override suspend fun saveFeed(feed: Feed) { val existing = feedDao.loadFeedWithUrl(feed.url) - val existingNostrFeeds = feedDao.getAllFeeds().filter { it.url.isAdaptedUrlFromNostrUri() } // Don't want to remove existing feed on OPML imports if (existing != null) { feedDao.updateFeed(feed.copy(id = existing.id)) } else { - if (feed.url.isAdaptedUrlFromNostrUri()) { - val potentialNostrFeed = existingNostrFeeds.find { it.title == feed.title } - if (potentialNostrFeed != null) { - logDebug(LOG_TAG, "Nostr feed with title <${feed.title}> already exists. Updating feed.") - feedDao.updateFeed(feed.copy(id = potentialNostrFeed.id)) - } else { - feedDao.insertFeed(feed) - } - } else { - feedDao.insertFeed(feed) - } + feedDao.insertFeed(feed) } } diff --git a/app/src/main/java/com/nononsenseapps/feeder/model/opml/OpmlPullParser.kt b/app/src/main/java/com/nononsenseapps/feeder/model/opml/OpmlPullParser.kt index de669cb558..74c2d653c6 100644 --- a/app/src/main/java/com/nononsenseapps/feeder/model/opml/OpmlPullParser.kt +++ b/app/src/main/java/com/nononsenseapps/feeder/model/opml/OpmlPullParser.kt @@ -6,6 +6,7 @@ import com.nononsenseapps.feeder.db.room.Feed import com.nononsenseapps.feeder.model.OPMLParserHandler import com.nononsenseapps.feeder.util.Either import com.nononsenseapps.feeder.util.flatMap +import com.nononsenseapps.feeder.util.getOrCreateFromUri import com.nononsenseapps.feeder.util.isNostrUri import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.withContext @@ -249,7 +250,7 @@ class OpmlPullParser(private val opmlToDb: OPMLParserHandler) { ) try { val parsedUrlOrUri = parser.getAttributeValue(null, ATTR_XMLURL) - val feedUrl = URL(if (parsedUrlOrUri.isNostrUri()) "https://njump.me/$parsedUrlOrUri" else parsedUrlOrUri) + val feedUrl = URL(parsedUrlOrUri.getOrCreateFromUri()) val feed = Feed( // Ensure not both are empty string: title will get replaced on sync diff --git a/app/src/main/java/com/nononsenseapps/feeder/ui/Constants.kt b/app/src/main/java/com/nononsenseapps/feeder/ui/Constants.kt index 6fcaf553de..01564753f1 100644 --- a/app/src/main/java/com/nononsenseapps/feeder/ui/Constants.kt +++ b/app/src/main/java/com/nononsenseapps/feeder/ui/Constants.kt @@ -14,3 +14,5 @@ const val ARG_FEED_FULL_TEXT_BY_DEFAULT = "feed_full_text_by_default" const val ARG_FEED_OPEN_ARTICLES_WITH = "feed_open_articles_with" const val ARG_URL = "url" const val ARG_ONLY_NEW = "only_new" + +const val NOSTR_URI_PREFIX = "nostr:" diff --git a/app/src/main/java/com/nononsenseapps/feeder/ui/compose/editfeed/CreateFeedScreenViewModel.kt b/app/src/main/java/com/nononsenseapps/feeder/ui/compose/editfeed/CreateFeedScreenViewModel.kt index 3187c081c8..6da0cc2a81 100644 --- a/app/src/main/java/com/nononsenseapps/feeder/ui/compose/editfeed/CreateFeedScreenViewModel.kt +++ b/app/src/main/java/com/nononsenseapps/feeder/ui/compose/editfeed/CreateFeedScreenViewModel.kt @@ -14,6 +14,7 @@ import com.nononsenseapps.feeder.background.runOnceRssSync import com.nononsenseapps.feeder.base.DIAwareViewModel import com.nononsenseapps.feeder.db.room.Feed import com.nononsenseapps.feeder.ui.compose.utils.mutableSavedStateOf +import com.nononsenseapps.feeder.util.getOrCreateFromUri import com.nononsenseapps.feeder.util.isNostrUri import com.nononsenseapps.feeder.util.sloppyLinkToStrictURLOrNull import kotlinx.coroutines.launch @@ -31,12 +32,10 @@ class CreateFeedScreenViewModel( // These three are updated as a result of url/uri updating override var isNotValidUrl by mutableStateOf(false) override var isOkToSave: Boolean by mutableStateOf(false) - override var isNostrUri: Boolean by mutableStateOf(false) override var feedUrl: String by mutableSavedStateOf(state, "") { value -> - isNotValidUrl = !isValidUrl(value) - isNostrUri = value.isNostrUri() - isOkToSave = isValidUrl(value) || isNostrUri + isNotValidUrl = !isValidUrlOrUri(value) + isOkToSave = isValidUrlOrUri(value) } override var feedTitle: String by mutableSavedStateOf(state, "") override var feedTag: String by mutableSavedStateOf(state, "") @@ -84,11 +83,11 @@ class CreateFeedScreenViewModel( val feedId = repository.saveFeed( Feed( - url = URL(if (isNostrUri) "https://njump.me/$feedUrl" else feedUrl), + url = URL(feedUrl.getOrCreateFromUri()), title = feedTitle, customTitle = feedTitle, tag = feedTag, - fullTextByDefault = if (isNostrUri) false else fullTextByDefault, + fullTextByDefault = if (feedUrl.isNostrUri()) false else fullTextByDefault, notify = notify, skipDuplicates = skipDuplicates, openArticlesWith = articleOpener, diff --git a/app/src/main/java/com/nononsenseapps/feeder/ui/compose/editfeed/EditFeedScreen.kt b/app/src/main/java/com/nononsenseapps/feeder/ui/compose/editfeed/EditFeedScreen.kt index 5b5f4ee741..0190f9b0c2 100644 --- a/app/src/main/java/com/nononsenseapps/feeder/ui/compose/editfeed/EditFeedScreen.kt +++ b/app/src/main/java/com/nononsenseapps/feeder/ui/compose/editfeed/EditFeedScreen.kt @@ -84,6 +84,7 @@ import com.nononsenseapps.feeder.ui.compose.utils.LocalWindowSizeMetrics import com.nononsenseapps.feeder.ui.compose.utils.ScreenType import com.nononsenseapps.feeder.ui.compose.utils.getScreenType import com.nononsenseapps.feeder.ui.compose.utils.rememberApiPermissionState +import com.nononsenseapps.feeder.util.isNostrUri @Composable fun CreateFeedScreen( @@ -351,9 +352,9 @@ fun ColumnScope.LeftContent( value = viewState.feedUrl, onValueChange = { viewState.feedUrl = it.trim() }, label = { - Text(stringResource(id = R.string.url)) + Text(stringResource(id = R.string.url_or_uri)) }, - isError = !viewState.isNostrUri && viewState.isNotValidUrl, + isError = viewState.isNotValidUrl, keyboardOptions = KeyboardOptions( capitalization = KeyboardCapitalization.None, @@ -376,10 +377,10 @@ fun ColumnScope.LeftContent( focusManager.moveFocus(FocusDirection.Down) }, ) - AnimatedVisibility(visible = !viewState.isNostrUri && viewState.isNotValidUrl) { + AnimatedVisibility(visible = viewState.isNotValidUrl) { Text( textAlign = TextAlign.Center, - text = stringResource(R.string.invalid_url), + text = stringResource(R.string.invalid_url_or_uri), style = MaterialTheme.typography.labelMedium.copy(color = MaterialTheme.colorScheme.error), ) } @@ -488,8 +489,8 @@ fun ColumnScope.RightContent( ) { SwitchSetting( title = stringResource(id = R.string.fetch_full_articles_by_default), - checked = if (viewState.isNostrUri) false else viewState.fullTextByDefault, - enabled = !viewState.isNostrUri, + checked = viewState.fullTextByDefault, + enabled = !viewState.feedUrl.isNostrUri(), icon = null, modifier = Modifier @@ -571,7 +572,6 @@ interface EditFeedScreenState { var articleOpener: String var alternateId: Boolean val isOkToSave: Boolean - val isNostrUri: Boolean val isNotValidUrl: Boolean val isOpenItemWithBrowser: Boolean val isOpenItemWithCustomTab: Boolean @@ -586,7 +586,6 @@ fun EditFeedScreenState(): EditFeedScreenState = ScreenState() private class ScreenState( override val isOkToSave: Boolean = false, - override val isNostrUri: Boolean = false, override val isNotValidUrl: Boolean = false, override val isOpenItemWithBrowser: Boolean = false, override val isOpenItemWithCustomTab: Boolean = false, diff --git a/app/src/main/java/com/nononsenseapps/feeder/ui/compose/editfeed/EditFeedScreenViewModel.kt b/app/src/main/java/com/nononsenseapps/feeder/ui/compose/editfeed/EditFeedScreenViewModel.kt index 016d119e56..a94e79f1d2 100644 --- a/app/src/main/java/com/nononsenseapps/feeder/ui/compose/editfeed/EditFeedScreenViewModel.kt +++ b/app/src/main/java/com/nononsenseapps/feeder/ui/compose/editfeed/EditFeedScreenViewModel.kt @@ -14,6 +14,7 @@ import com.nononsenseapps.feeder.background.runOnceRssSync import com.nononsenseapps.feeder.base.DIAwareViewModel import com.nononsenseapps.feeder.db.room.Feed import com.nononsenseapps.feeder.ui.compose.utils.mutableSavedStateOf +import com.nononsenseapps.feeder.util.getOrCreateFromUri import com.nononsenseapps.feeder.util.isNostrUri import kotlinx.coroutines.launch import org.kodein.di.DI @@ -34,12 +35,10 @@ class EditFeedScreenViewModel( // These two are updated as a result of url updating override var isNotValidUrl by mutableStateOf(false) override var isOkToSave: Boolean by mutableStateOf(false) - override var isNostrUri: Boolean by mutableStateOf(false) override var feedUrl: String by mutableSavedStateOf(state, "") { value -> - isNotValidUrl = !isValidUrl(value) - isNostrUri = value.isNostrUri() - isOkToSave = isValidUrl(value) || isNostrUri + isNotValidUrl = !isValidUrlOrUri(value) + isOkToSave = isValidUrlOrUri(value) } override var feedTitle: String by mutableSavedStateOf(state, "") override var feedTag: String by mutableSavedStateOf(state, "") @@ -126,11 +125,11 @@ class EditFeedScreenViewModel( val updatedFeed = feed.copy( - url = URL(if (isNostrUri) "https://njump.me/$feedUrl" else feedUrl), + url = URL(feedUrl.getOrCreateFromUri()), title = feedTitle, customTitle = feedTitle, tag = feedTag, - fullTextByDefault = if (isNostrUri) false else fullTextByDefault, + fullTextByDefault = if (feedUrl.isNostrUri()) false else fullTextByDefault, notify = notify, skipDuplicates = skipDuplicates, openArticlesWith = articleOpener, @@ -156,10 +155,14 @@ class EditFeedScreenViewModel( } } -internal fun isValidUrl(value: String): Boolean { +internal fun isValidUrlOrUri(value: String): Boolean { return try { - URL(value) - true + if (value.isNostrUri()) { + true + } else { + URL(value) + true + } } catch (e: Exception) { false } diff --git a/app/src/main/java/com/nononsenseapps/feeder/ui/compose/searchfeed/SearchFeedScreen.kt b/app/src/main/java/com/nononsenseapps/feeder/ui/compose/searchfeed/SearchFeedScreen.kt index 688a3e756f..c762764a49 100644 --- a/app/src/main/java/com/nononsenseapps/feeder/ui/compose/searchfeed/SearchFeedScreen.kt +++ b/app/src/main/java/com/nononsenseapps/feeder/ui/compose/searchfeed/SearchFeedScreen.kt @@ -88,6 +88,7 @@ import com.nononsenseapps.feeder.ui.compose.utils.ScreenType import com.nononsenseapps.feeder.ui.compose.utils.StableHolder import com.nononsenseapps.feeder.ui.compose.utils.getScreenType import com.nononsenseapps.feeder.ui.compose.utils.stableListHolderOf +import com.nononsenseapps.feeder.util.getOrCreateFromUri import com.nononsenseapps.feeder.util.isNostrUri import com.nononsenseapps.feeder.util.sloppyLinkToStrictURLNoThrows import kotlinx.coroutines.flow.onCompletion @@ -228,11 +229,11 @@ fun SearchFeedView( // If screen is opened from intent with pre-filled URL, trigger search directly LaunchedEffect(Unit) { if (results.item.isEmpty() && errors.item.isEmpty() && feedUrl.isNotBlank() && - (isValidUrl(feedUrl) || feedUrl.isNostrUri()) + (isValidUrl(feedUrl)) ) { onSearchCallback( sloppyLinkToStrictURLNoThrows( - if (feedUrl.isNostrUri()) "https://njump.me/$feedUrl" else feedUrl, + feedUrl.getOrCreateFromUri(), ), ) } @@ -350,7 +351,7 @@ fun ColumnScope.leftContent( label = { Text(stringResource(id = R.string.add_feed_search_hint)) }, - isError = isNotValidUrl && !isNostrUri, + isError = isNotValidUrl, keyboardOptions = KeyboardOptions( capitalization = KeyboardCapitalization.None, @@ -363,7 +364,7 @@ fun ColumnScope.leftContent( onSearch = { if (isValidUrl || isNostrUri) { onSearch( - sloppyLinkToStrictURLNoThrows(if (isNostrUri) "https://njump.me/$feedUrl" else feedUrl), + sloppyLinkToStrictURLNoThrows(feedUrl.getOrCreateFromUri()), ) keyboardController?.hide() } @@ -374,9 +375,9 @@ fun ColumnScope.leftContent( modifier .width(dimens.maxContentWidth) .interceptKey(Key.Enter) { - if (isValidUrl(feedUrl) || feedUrl.isNostrUri()) { + if (isValidUrl(feedUrl)) { onSearch( - sloppyLinkToStrictURLNoThrows(if (isNostrUri) "https://njump.me/$feedUrl" else feedUrl), + sloppyLinkToStrictURLNoThrows(feedUrl.getOrCreateFromUri()), ) keyboardController?.hide() } @@ -388,18 +389,11 @@ fun ColumnScope.leftContent( ) OutlinedButton( - enabled = isValidUrl || isNostrUri, + enabled = isValidUrl, onClick = { - if (isNostrUri) { + if (isValidUrl) { try { - onSearch(sloppyLinkToStrictURLNoThrows("https://njump.me/$feedUrl")) - clearFocus() - } catch (e: Exception) { - Log.e(LOG_TAG, "Can't search Nostr URI", e) - } - } else if (isValidUrl) { - try { - onSearch(sloppyLinkToStrictURLNoThrows(feedUrl)) + onSearch(sloppyLinkToStrictURLNoThrows(feedUrl.getOrCreateFromUri())) clearFocus() } catch (e: Exception) { Log.e(LOG_TAG, "Can't search", e) @@ -688,12 +682,16 @@ private fun isValidUrl(url: String): Boolean { return false } return try { - try { - URL(url) - true - } catch (_: MalformedURLException) { - URL("http://$url") + if (url.isNostrUri()) { true + } else { + try { + URL(url) + true + } catch (_: MalformedURLException) { + URL("http://$url") + true + } } } catch (e: Exception) { false diff --git a/app/src/main/java/com/nononsenseapps/feeder/ui/compose/searchfeed/SearchFeedViewModel.kt b/app/src/main/java/com/nononsenseapps/feeder/ui/compose/searchfeed/SearchFeedViewModel.kt index b7303b563b..ccfe9e0fe8 100644 --- a/app/src/main/java/com/nononsenseapps/feeder/ui/compose/searchfeed/SearchFeedViewModel.kt +++ b/app/src/main/java/com/nononsenseapps/feeder/ui/compose/searchfeed/SearchFeedViewModel.kt @@ -3,6 +3,8 @@ package com.nononsenseapps.feeder.ui.compose.searchfeed import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.setValue +import com.nononsenseapps.feeder.FeederApplication +import com.nononsenseapps.feeder.R import com.nononsenseapps.feeder.archmodel.Repository import com.nononsenseapps.feeder.base.DIAwareViewModel import com.nononsenseapps.feeder.model.FeedParser @@ -29,6 +31,7 @@ import java.time.Instant class SearchFeedViewModel(di: DI) : DIAwareViewModel(di) { private val feedParser: FeedParser by instance() private val repository: Repository by instance() + private val application: FeederApplication by instance() private var siteMetaData: Either by mutableStateOf( Either.Left( @@ -56,23 +59,10 @@ class SearchFeedViewModel(di: DI) : DIAwareViewModel(di) { SearchResult( title = metadata.name, url = metadata.uri, - description = "Nostr Articles by ${metadata.name}", + description = application.applicationContext.getString(R.string.nostr_feed_description, metadata.name), feedImage = metadata.imageUrl, ) } - -// feedParser.findNostrFeed(metadata) -// .map { nostrFeed -> -// SearchResult( -// title = nostrFeed.title ?: "", -// url = nostrFeed.feed_url ?: metadata.uri, -// description = nostrFeed.description ?: "", -// feedImage = nostrFeed.icon ?: "" -// ) -// } -// .onLeft { -// -// } } } .flowOn(Dispatchers.Default) diff --git a/app/src/main/java/com/nononsenseapps/feeder/ui/compose/settings/OpenAISection.kt b/app/src/main/java/com/nononsenseapps/feeder/ui/compose/settings/OpenAISection.kt index 88a1d0316c..8277a71fd4 100644 --- a/app/src/main/java/com/nononsenseapps/feeder/ui/compose/settings/OpenAISection.kt +++ b/app/src/main/java/com/nononsenseapps/feeder/ui/compose/settings/OpenAISection.kt @@ -213,7 +213,7 @@ fun OpenAISectionEdit( Text(OpenAIHost.OpenAI.baseUrl) }, label = { - Text(stringResource(R.string.url)) + Text(stringResource(R.string.url_or_uri)) }, onValueChange = { onEvent(OpenAISettingsEvent.UpdateSettings(current.copy(baseUrl = it))) diff --git a/app/src/main/java/com/nononsenseapps/feeder/util/LinkUtils.kt b/app/src/main/java/com/nononsenseapps/feeder/util/LinkUtils.kt index a7ee891b7a..3f8586ed9a 100644 --- a/app/src/main/java/com/nononsenseapps/feeder/util/LinkUtils.kt +++ b/app/src/main/java/com/nononsenseapps/feeder/util/LinkUtils.kt @@ -1,5 +1,6 @@ package com.nononsenseapps.feeder.util +import com.nononsenseapps.feeder.ui.NOSTR_URI_PREFIX import java.net.MalformedURLException import java.net.URI import java.net.URISyntaxException @@ -99,9 +100,8 @@ fun relativeLinkIntoAbsoluteOrThrow( URL(base, link) } -fun String.isNostrUri(): Boolean { - val nostrPrefix = "nostr:" - return this.startsWith(nostrPrefix) && length > nostrPrefix.length -} +fun String.isNostrUri(): Boolean = startsWith(NOSTR_URI_PREFIX) && length > NOSTR_URI_PREFIX.length fun URL.isAdaptedUrlFromNostrUri(): Boolean = this.toString().startsWith("https://njump.me") + +fun String.getOrCreateFromUri(): String = if (isNostrUri()) "https://njump.me/$this" else this