Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import io.getstream.feeds.android.client.api.file.FeedUploader
import io.getstream.feeds.android.client.api.model.ActivityData
import io.getstream.feeds.android.client.api.model.AppData
import io.getstream.feeds.android.client.api.model.BatchFollowData
import io.getstream.feeds.android.client.api.model.BookmarkFolderData
import io.getstream.feeds.android.client.api.model.CollectionData
import io.getstream.feeds.android.client.api.model.FeedId
import io.getstream.feeds.android.client.api.model.FeedsConfig
Expand Down Expand Up @@ -77,6 +78,7 @@ import io.getstream.feeds.android.network.models.FollowBatchRequest
import io.getstream.feeds.android.network.models.GetOGResponse
import io.getstream.feeds.android.network.models.ListDevicesResponse
import io.getstream.feeds.android.network.models.UnfollowBatchRequest
import io.getstream.feeds.android.network.models.UpdateBookmarkFolderRequest
import io.getstream.feeds.android.network.models.UpdateCollectionsRequest
import io.getstream.feeds.android.network.models.UpsertPushPreferencesRequest
import io.getstream.feeds.android.network.models.UpsertPushPreferencesResponse
Expand Down Expand Up @@ -318,6 +320,27 @@ public interface FeedsClient {
*/
public fun bookmarkFolderList(query: BookmarkFoldersQuery): BookmarkFolderList

/**
* Updates a bookmark folder by its ID.
*
* @param folderId The unique identifier of the bookmark folder to update.
* @param request The request containing the updated folder data.
* @return A [Result] containing the updated [BookmarkFolderData] if successful, or an error if
* the operation fails.
*/
public suspend fun updateBookmarkFolder(
folderId: String,
request: UpdateBookmarkFolderRequest,
): Result<BookmarkFolderData>

/**
* Deletes a bookmark folder by its ID. All bookmarks in the folder will also be deleted.
*
* @param folderId The unique identifier of the bookmark folder to delete.
* @return A [Result] indicating success or failure of the deletion operation.
*/
public suspend fun deleteBookmarkFolder(folderId: String): Result<Unit>

/**
* Creates a comment list instance based on the provided query.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import io.getstream.feeds.android.network.models.UpdateBookmarkRequest
import io.getstream.feeds.android.network.models.UpdateCommentRequest
import io.getstream.feeds.android.network.models.UpdateFeedMembersRequest
import io.getstream.feeds.android.network.models.UpdateFeedRequest
import io.getstream.feeds.android.network.models.UpdateFollowRequest

/**
* A feed represents a collection of activities and provides methods to interact with them.
Expand Down Expand Up @@ -166,6 +167,18 @@ public interface Feed {
deleteNotificationActivity: Boolean? = null,
): Result<Unit>

/**
* Restores a soft-deleted activity.
*
* Only the activity owner can restore their own activities (for client-side requests).
* Hard-deleted activities cannot be restored.
*
* @param id The unique identifier of the activity to restore.
* @return A [Result] containing the restored [ActivityData] if successful, or an error if the
* operation fails.
*/
public suspend fun restoreActivity(id: String): Result<ActivityData>

/**
* Marks an activity as read or unread.
*
Expand Down Expand Up @@ -328,6 +341,21 @@ public interface Feed {
pushPreference: FollowRequest.PushPreference? = null,
): Result<FollowData>

/**
* Updates a follow relationship with new custom data or push preferences.
*
* @param targetFid The target feed identifier of the follow to update.
* @param custom Additional data for the follow relationship.
* @param pushPreference Push notification preferences for the follow.
* @return A [Result] containing the updated [FollowData] if successful, or an error if the
* operation fails.
*/
public suspend fun updateFollow(
targetFid: FeedId,
custom: Map<String, Any>? = null,
pushPreference: UpdateFollowRequest.PushPreference? = null,
): Result<FollowData>

/**
* Unfollows another feed.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import io.getstream.feeds.android.client.api.Moderation
import io.getstream.feeds.android.client.api.file.FeedUploader
import io.getstream.feeds.android.client.api.model.ActivityData
import io.getstream.feeds.android.client.api.model.BatchFollowData
import io.getstream.feeds.android.client.api.model.BookmarkFolderData
import io.getstream.feeds.android.client.api.model.FeedId
import io.getstream.feeds.android.client.api.model.FollowData
import io.getstream.feeds.android.client.api.model.ModelUpdates
Expand Down Expand Up @@ -96,6 +97,7 @@ import io.getstream.feeds.android.client.internal.state.PollListImpl
import io.getstream.feeds.android.client.internal.state.PollVoteListImpl
import io.getstream.feeds.android.client.internal.state.UserListImpl
import io.getstream.feeds.android.client.internal.state.event.StateEventEnricher
import io.getstream.feeds.android.client.internal.state.event.StateUpdateEvent
import io.getstream.feeds.android.client.internal.state.event.StateUpdateEvent.FollowBatchUpdate
import io.getstream.feeds.android.client.internal.state.event.handler.OnNewActivity
import io.getstream.feeds.android.client.internal.state.event.toModel
Expand All @@ -109,6 +111,7 @@ import io.getstream.feeds.android.network.models.DeleteActivitiesRequest
import io.getstream.feeds.android.network.models.DeleteActivitiesResponse
import io.getstream.feeds.android.network.models.FollowBatchRequest
import io.getstream.feeds.android.network.models.UnfollowBatchRequest
import io.getstream.feeds.android.network.models.UpdateBookmarkFolderRequest
import io.getstream.feeds.android.network.models.WSEvent
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.channels.BufferOverflow
Expand Down Expand Up @@ -308,6 +311,21 @@ internal class FeedsClientImpl(
subscriptionManager = stateEventsSubscriptionManager,
)

override suspend fun updateBookmarkFolder(
folderId: String,
request: UpdateBookmarkFolderRequest,
): Result<BookmarkFolderData> {
return bookmarksRepository.updateBookmarkFolder(folderId, request).onSuccess {
stateEventsSubscriptionManager.onEvent(StateUpdateEvent.BookmarkFolderUpdated(it))
}
}

override suspend fun deleteBookmarkFolder(folderId: String): Result<Unit> {
return bookmarksRepository.deleteBookmarkFolder(folderId).onSuccess {
stateEventsSubscriptionManager.onEvent(StateUpdateEvent.BookmarkFolderDeleted(folderId))
}
}

override fun commentList(query: CommentsQuery): CommentList =
CommentListImpl(
query = query,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,14 @@ internal interface ActivitiesRepository {
*/
suspend fun deleteActivities(request: DeleteActivitiesRequest): Result<DeleteActivitiesResponse>

/**
* Restores a soft-deleted activity.
*
* @param activityId The ID of the activity to restore.
* @return A [Result] containing the restored [ActivityData] or an error.
*/
suspend fun restoreActivity(activityId: String): Result<ActivityData>

/**
* Retrieves an activity by its ID.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,10 @@ internal class ActivitiesRepositoryImpl(
request: DeleteActivitiesRequest
): Result<DeleteActivitiesResponse> = runSafely { api.deleteActivities(request) }

override suspend fun restoreActivity(activityId: String): Result<ActivityData> = runSafely {
api.restoreActivity(id = activityId).activity.toModel()
}

override suspend fun getActivity(activityId: String): Result<ActivityData> = runSafely {
api.getActivity(activityId).activity.toModel()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import io.getstream.feeds.android.client.api.state.query.BookmarkFoldersQuery
import io.getstream.feeds.android.client.api.state.query.BookmarksQuery
import io.getstream.feeds.android.client.internal.model.PaginationResult
import io.getstream.feeds.android.network.models.AddBookmarkRequest
import io.getstream.feeds.android.network.models.UpdateBookmarkFolderRequest
import io.getstream.feeds.android.network.models.UpdateBookmarkRequest

internal interface BookmarksRepository {
Expand All @@ -40,4 +41,11 @@ internal interface BookmarksRepository {
suspend fun queryBookmarkFolders(
query: BookmarkFoldersQuery
): Result<PaginationResult<BookmarkFolderData>>

suspend fun updateBookmarkFolder(
folderId: String,
request: UpdateBookmarkFolderRequest,
): Result<BookmarkFolderData>

suspend fun deleteBookmarkFolder(folderId: String): Result<Unit>
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import io.getstream.feeds.android.client.internal.model.toModel
import io.getstream.feeds.android.client.internal.state.query.toRequest
import io.getstream.feeds.android.network.apis.FeedsApi
import io.getstream.feeds.android.network.models.AddBookmarkRequest
import io.getstream.feeds.android.network.models.UpdateBookmarkFolderRequest
import io.getstream.feeds.android.network.models.UpdateBookmarkRequest

/**
Expand Down Expand Up @@ -76,4 +77,15 @@ internal class BookmarksRepositoryImpl(private val api: FeedsApi) : BookmarksRep
pagination = PaginationData(response.next, response.prev),
)
}

override suspend fun updateBookmarkFolder(
folderId: String,
request: UpdateBookmarkFolderRequest,
): Result<BookmarkFolderData> = runSafely {
api.updateBookmarkFolder(folderId, request).bookmarkFolder.toModel()
}

override suspend fun deleteBookmarkFolder(folderId: String): Result<Unit> = runSafely {
api.deleteBookmarkFolder(folderId)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import io.getstream.feeds.android.network.models.RejectFollowRequest
import io.getstream.feeds.android.network.models.UnfollowBatchRequest
import io.getstream.feeds.android.network.models.UpdateFeedMembersRequest
import io.getstream.feeds.android.network.models.UpdateFeedRequest
import io.getstream.feeds.android.network.models.UpdateFollowRequest

/**
* Represents the repository for managing feeds. Performs requests and transforms API models to
Expand Down Expand Up @@ -98,6 +99,8 @@ internal interface FeedsRepository {

suspend fun rejectFollow(request: RejectFollowRequest): Result<FollowData>

suspend fun updateFollow(request: UpdateFollowRequest): Result<FollowData>

// END: Follows

// BEGIN: Members
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ import io.getstream.feeds.android.network.models.RejectFollowRequest
import io.getstream.feeds.android.network.models.UnfollowBatchRequest
import io.getstream.feeds.android.network.models.UpdateFeedMembersRequest
import io.getstream.feeds.android.network.models.UpdateFeedRequest
import io.getstream.feeds.android.network.models.UpdateFollowRequest

/**
* Default implementation of the [FeedsRepository] interface.
Expand Down Expand Up @@ -175,6 +176,11 @@ internal class FeedsRepositoryImpl(private val api: FeedsApi) : FeedsRepository
api.rejectFollow(request).follow.toModel()
}

override suspend fun updateFollow(request: UpdateFollowRequest): Result<FollowData> =
runSafely {
api.updateFollow(request).follow.toModel()
}

override suspend fun updateFeedMembers(
feedGroupId: String,
feedId: String,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ import io.getstream.feeds.android.network.models.UpdateBookmarkRequest
import io.getstream.feeds.android.network.models.UpdateCommentRequest
import io.getstream.feeds.android.network.models.UpdateFeedMembersRequest
import io.getstream.feeds.android.network.models.UpdateFeedRequest
import io.getstream.feeds.android.network.models.UpdateFollowRequest

/**
* A feed represents a collection of activities and provides methods to interact with them.
Expand Down Expand Up @@ -218,6 +219,10 @@ internal class FeedImpl(
}
}

override suspend fun restoreActivity(id: String): Result<ActivityData> {
return activitiesRepository.restoreActivity(id)
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.

override suspend fun markActivity(request: MarkActivityRequest): Result<Unit> {
return activitiesRepository.markActivity(
feedGroupId = group,
Expand Down Expand Up @@ -369,6 +374,23 @@ internal class FeedImpl(
}
}

override suspend fun updateFollow(
targetFid: FeedId,
custom: Map<String, Any>?,
pushPreference: UpdateFollowRequest.PushPreference?,
): Result<FollowData> {
val request =
UpdateFollowRequest(
source = fid.rawValue,
target = targetFid.rawValue,
custom = custom,
pushPreference = pushPreference,
)
return feedsRepository.updateFollow(request).onSuccess {
subscriptionManager.onEvent(StateUpdateEvent.FollowUpdated(it))
}
}

override suspend fun unfollow(
targetFid: FeedId,
deleteNotificationActivity: Boolean?,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ import io.getstream.feeds.android.network.models.MarkActivityRequest
import io.getstream.feeds.android.network.models.QueryActivitiesResponse
import io.getstream.feeds.android.network.models.QueryActivityReactionsRequest
import io.getstream.feeds.android.network.models.QueryActivityReactionsResponse
import io.getstream.feeds.android.network.models.RestoreActivityResponse
import io.getstream.feeds.android.network.models.UpdateActivityPartialRequest
import io.getstream.feeds.android.network.models.UpdateActivityPartialResponse
import io.getstream.feeds.android.network.models.UpdateActivityRequest
Expand Down Expand Up @@ -336,4 +337,16 @@ internal class ActivitiesRepositoryImplTest {
repositoryResult = Unit,
)
}

@Test
fun `on restoreActivity, delegate to api`() {
val apiResult = RestoreActivityResponse("duration", activityResponse())

testDelegation(
apiFunction = { feedsApi.restoreActivity("activityId") },
repositoryCall = { repository.restoreActivity("activityId") },
apiResult = apiResult,
repositoryResult = apiResult.activity.toModel(),
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ import io.getstream.feeds.android.network.models.AddBookmarkResponse
import io.getstream.feeds.android.network.models.DeleteBookmarkResponse
import io.getstream.feeds.android.network.models.QueryBookmarkFoldersResponse
import io.getstream.feeds.android.network.models.QueryBookmarksResponse
import io.getstream.feeds.android.network.models.UpdateBookmarkFolderRequest
import io.getstream.feeds.android.network.models.UpdateBookmarkFolderResponse
import io.getstream.feeds.android.network.models.UpdateBookmarkRequest
import io.getstream.feeds.android.network.models.UpdateBookmarkResponse
import io.mockk.mockk
Expand Down Expand Up @@ -140,4 +142,27 @@ internal class BookmarksRepositoryImplTest {
),
)
}

@Test
fun `on updateBookmarkFolder, delegate to api`() = runTest {
val request = UpdateBookmarkFolderRequest()
val apiResult = UpdateBookmarkFolderResponse("duration", bookmarkFolderResponse())

testDelegation(
apiFunction = { feedsApi.updateBookmarkFolder("folder-1", request) },
repositoryCall = { repository.updateBookmarkFolder("folder-1", request) },
apiResult = apiResult,
repositoryResult = apiResult.bookmarkFolder.toModel(),
)
}

@Test
fun `on deleteBookmarkFolder, delegate to api`() = runTest {
testDelegation(
apiFunction = { feedsApi.deleteBookmarkFolder("folder-1") },
repositoryCall = { repository.deleteBookmarkFolder("folder-1") },
apiResult = Unit,
repositoryResult = Unit,
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ import io.getstream.feeds.android.network.models.UnfollowPair
import io.getstream.feeds.android.network.models.UnfollowResponse
import io.getstream.feeds.android.network.models.UpdateFeedMembersRequest
import io.getstream.feeds.android.network.models.UpdateFeedRequest
import io.getstream.feeds.android.network.models.UpdateFollowRequest
import io.getstream.feeds.android.network.models.UpdateFollowResponse
import io.mockk.mockk
import kotlinx.coroutines.test.runTest
import org.junit.Test
Expand Down Expand Up @@ -235,6 +237,24 @@ internal class FeedsRepositoryImplTest {
)
}

@Test
fun `on updateFollow, delegate to api`() = runTest {
val request =
UpdateFollowRequest(
source = "source",
target = "target",
custom = mapOf("key" to "value"),
)
val apiResult = UpdateFollowResponse("duration", followResponse())

testDelegation(
apiFunction = { feedsApi.updateFollow(request) },
repositoryCall = { repository.updateFollow(request) },
apiResult = apiResult,
repositoryResult = apiResult.follow.toModel(),
)
}

@Test
fun `on updateFeedMembers, delegate to api`() = runTest {
val request = UpdateFeedMembersRequest(UpdateFeedMembersRequest.Operation.Remove)
Expand Down
Loading
Loading