Skip to content

Commit

Permalink
[1.88.*] Pre-release merge (#356)
Browse files Browse the repository at this point in the history
  • Loading branch information
tramline-github[bot] authored Mar 3, 2024
2 parents 303b112 + 35b3de1 commit 0071091
Show file tree
Hide file tree
Showing 17 changed files with 497 additions and 233 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/*
* Copyright 2024 Sasikanth Miriyampalli
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package dev.sasikanth.rss.reader.resources.icons

import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.PathFillType.Companion.NonZero
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.graphics.StrokeCap.Companion.Butt
import androidx.compose.ui.graphics.StrokeJoin.Companion.Miter
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.graphics.vector.ImageVector.Builder
import androidx.compose.ui.graphics.vector.path
import androidx.compose.ui.unit.dp

val TwineIcons.DeleteOutline: ImageVector
get() {
if (deleteOutline != null) {
return deleteOutline!!
}
deleteOutline =
Builder(
name = "Delete",
defaultWidth = 21.0.dp,
defaultHeight = 20.0.dp,
viewportWidth = 21.0f,
viewportHeight = 20.0f
)
.apply {
path(
fill = SolidColor(Color(0xFF00E0BB)),
stroke = null,
strokeLineWidth = 0.0f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero
) {
moveTo(7.8334f, 2.5001f)
verticalLineTo(3.3335f)
horizontalLineTo(3.6667f)
verticalLineTo(5.0001f)
horizontalLineTo(4.5001f)
verticalLineTo(15.8335f)
curveTo(4.5001f, 16.2755f, 4.6757f, 16.6994f, 4.9882f, 17.012f)
curveTo(5.3008f, 17.3245f, 5.7247f, 17.5001f, 6.1667f, 17.5001f)
horizontalLineTo(14.5001f)
curveTo(14.9421f, 17.5001f, 15.366f, 17.3245f, 15.6786f, 17.012f)
curveTo(15.9912f, 16.6994f, 16.1667f, 16.2755f, 16.1667f, 15.8335f)
verticalLineTo(5.0001f)
horizontalLineTo(17.0001f)
verticalLineTo(3.3335f)
horizontalLineTo(12.8334f)
verticalLineTo(2.5001f)
horizontalLineTo(7.8334f)
close()
moveTo(6.1667f, 5.0001f)
horizontalLineTo(14.5001f)
verticalLineTo(15.8335f)
horizontalLineTo(6.1667f)
verticalLineTo(5.0001f)
close()
moveTo(7.8334f, 6.6668f)
verticalLineTo(14.1668f)
horizontalLineTo(9.5001f)
verticalLineTo(6.6668f)
horizontalLineTo(7.8334f)
close()
moveTo(11.1667f, 6.6668f)
verticalLineTo(14.1668f)
horizontalLineTo(12.8334f)
verticalLineTo(6.6668f)
horizontalLineTo(11.1667f)
close()
}
}
.build()
return deleteOutline!!
}

private var deleteOutline: ImageVector? = null
Original file line number Diff line number Diff line change
Expand Up @@ -115,12 +115,12 @@ val EnTwineStrings =
openSource = "Support Open Source",
openSourceDesc =
"Twine is an open source project and is available for free to use. Click here to know more on how to support this project or, view source code of Twine or some of my other popular projects.",
markAsRead = "Mark as Read",
markAsUnRead = "Mark as Unread",
markAsRead = "Mark as read",
markAsUnRead = "Mark as unread",
removeFeed = "Remove feed",
delete = "Delete",
removeFeedDesc = { "Do you want to remove \"${it}\"?" },
alwaysFetchSourceArticle = "Always fetch source article in Reading View",
alwaysFetchSourceArticle = "Always fetch full articles in reader view",
getFeedInfo = "Get Info",
newTag = "New tag",
tags = "Tags",
Expand All @@ -129,5 +129,16 @@ val EnTwineStrings =
tagSaveButton = "Save",
deleteTagTitle = "Delete tag?",
deleteTagDesc =
"Tag will be deleted and removed from all the assigned feeds. Your feeds won't be deleted"
"Tag will be deleted and removed from all the assigned feeds. Your feeds won't be deleted",
feedOptionShare = "Share",
feedOptionWebsite = "Website",
feedOptionRemove = "Remove",
feedTitleHint = "Title",
noUnreadPostsInFeed = "No unread articles",
numberOfUnreadPostsInFeed = { numberOfUnreadPosts ->
when (numberOfUnreadPosts) {
1L -> "$numberOfUnreadPosts unread article"
else -> "$numberOfUnreadPosts unread articles"
}
}
)
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,12 @@ data class TwineStrings(
val tagSaveButton: String,
val deleteTagTitle: String,
val deleteTagDesc: String,
val feedOptionShare: String,
val feedOptionWebsite: String,
val feedOptionRemove: String,
val feedTitleHint: String,
val noUnreadPostsInFeed: String,
val numberOfUnreadPostsInFeed: (Long) -> String
)

object Locales {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,6 @@ sealed interface FeedEvent {

data class OnAlwaysFetchSourceArticleChanged(val newValue: Boolean, val feedLink: String) :
FeedEvent

data class OnMarkPostsAsRead(val feedLink: String) : FeedEvent
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,28 @@ import com.arkivanov.decompose.ComponentContext
import com.arkivanov.essenty.instancekeeper.InstanceKeeper
import com.arkivanov.essenty.instancekeeper.getOrCreate
import com.arkivanov.essenty.lifecycle.doOnCreate
import dev.sasikanth.rss.reader.home.ui.PostsType
import dev.sasikanth.rss.reader.repository.ObservableSelectedFeed
import dev.sasikanth.rss.reader.repository.RssRepository
import dev.sasikanth.rss.reader.repository.SettingsRepository
import dev.sasikanth.rss.reader.util.DispatchersProvider
import dev.sasikanth.rss.reader.utils.getTodayStartInstant
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import kotlinx.datetime.Instant
import me.tatarka.inject.annotations.Assisted
import me.tatarka.inject.annotations.Inject

Expand All @@ -47,6 +56,7 @@ internal typealias FeedPresenterFactory =
class FeedPresenter(
dispatchersProvider: DispatchersProvider,
rssRepository: RssRepository,
settingsRepository: SettingsRepository,
private val observableSelectedFeed: ObservableSelectedFeed,
@Assisted feedLink: String,
@Assisted componentContext: ComponentContext,
Expand All @@ -58,6 +68,7 @@ class FeedPresenter(
PresenterInstance(
dispatchersProvider = dispatchersProvider,
rssRepository = rssRepository,
settingsRepository = settingsRepository,
feedLink = feedLink,
observableSelectedFeed = observableSelectedFeed,
)
Expand All @@ -83,8 +94,9 @@ class FeedPresenter(
}

private class PresenterInstance(
dispatchersProvider: DispatchersProvider,
private val dispatchersProvider: DispatchersProvider,
private val rssRepository: RssRepository,
private val settingsRepository: SettingsRepository,
private val feedLink: String,
private val observableSelectedFeed: ObservableSelectedFeed,
) : InstanceKeeper.Instance {
Expand Down Expand Up @@ -112,6 +124,23 @@ class FeedPresenter(
is FeedEvent.OnFeedNameChanged -> onFeedNameUpdated(event.newFeedName, event.feedLink)
is FeedEvent.OnAlwaysFetchSourceArticleChanged ->
onAlwaysFetchSourceArticleChanged(event.newValue, event.feedLink)
is FeedEvent.OnMarkPostsAsRead -> onMarkPostsAsRead(event.feedLink)
}
}

private fun onMarkPostsAsRead(feedLink: String) {
coroutineScope.launch {
val postsType = withContext(dispatchersProvider.io) { settingsRepository.postsType.first() }
val postsAfter =
when (postsType) {
PostsType.ALL,
PostsType.UNREAD -> Instant.DISTANT_PAST
PostsType.TODAY -> {
getTodayStartInstant()
}
}

rssRepository.markPostsInFeedAsRead(feedLink = feedLink, postsAfter = postsAfter)
}
}

Expand All @@ -133,8 +162,24 @@ class FeedPresenter(

private fun init() {
coroutineScope.launch {
val feed = rssRepository.feed(feedLink)
_state.update { it.copy(feed = feed) }
val postsType = withContext(dispatchersProvider.io) { settingsRepository.postsType.first() }
val postsAfter =
when (postsType) {
PostsType.ALL,
PostsType.UNREAD -> Instant.DISTANT_PAST
PostsType.TODAY -> {
getTodayStartInstant()
}
}

rssRepository
.feed(feedLink, postsAfter)
.onEach { feed -> _state.update { it.copy(feed = feed) } }
.catch {
// no-op
// When we delete a feed, this flow crashes because, that feed is no longer available
}
.launchIn(coroutineScope)
}
}
}
Expand Down
Loading

0 comments on commit 0071091

Please sign in to comment.