Skip to content

Commit

Permalink
Merge pull request #8 from whitescent/explore-page
Browse files Browse the repository at this point in the history
  • Loading branch information
whitescent authored Dec 1, 2023
2 parents bd1ba82 + cd1fbd5 commit 51d069d
Show file tree
Hide file tree
Showing 27 changed files with 700 additions and 156 deletions.
4 changes: 2 additions & 2 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ android {
applicationId = "com.github.whitescent.mastify"
minSdk = 21
targetSdk = 34
versionCode = 8
versionName = "1.1.4-pre-alpha"
versionCode = 9
versionName = "1.2.0-pre-alpha"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {
useSupportLibrary = true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ class MastifyApp : Application(), ImageLoaderFactory {
add(VideoFrameDecoder.Factory())
}
.placeholder(R.drawable.image_placeholder)
.crossfade(true)
.build()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ data class StatusUiData(
val emojis: ImmutableList<Emoji>,
val attachments: ImmutableList<Status.Attachment>,
val actionable: Status,
val actionableId: String,
val reblogDisplayName: String,
val fullname: String,
val createdAt: String,
Expand All @@ -57,6 +56,8 @@ data class StatusUiData(
val hasUnloadedStatus: Boolean,
) {

val actionableId inline get() = reblog?.id ?: id

val parsedContent: String = Jsoup.parse(content).body().text()
val isInReplyTo inline get() = inReplyToId != null

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,61 +17,28 @@

package com.github.whitescent.mastify.data.repository

import androidx.paging.Pager
import androidx.paging.PagingConfig
import androidx.paging.PagingData
import at.connyduck.calladapter.networkresult.NetworkResult
import at.connyduck.calladapter.networkresult.fold
import com.github.whitescent.mastify.data.model.ui.StatusUiData
import com.github.whitescent.mastify.network.MastodonApi
import com.github.whitescent.mastify.network.model.search.SearchResult
import com.github.whitescent.mastify.paging.PublicTimelinePagingSource
import com.github.whitescent.mastify.paging.TrendingPagingSource
import kotlinx.coroutines.flow.Flow
import com.github.whitescent.mastify.network.model.trends.News
import javax.inject.Inject
import javax.inject.Singleton

@Singleton
class ExploreRepository @Inject constructor(
private val api: MastodonApi
) {

suspend fun getPreviewResultsForSearch(keyword: String): SearchPreviewResult {
if (keyword.isBlank()) return SearchPreviewResult.Success(null)
suspend fun getPreviewResultsForSearch(keyword: String): NetworkResult<SearchResult?> {
if (keyword.isBlank()) return NetworkResult.success(null)
return api.searchSync(query = keyword, limit = 10).fold(
{
SearchPreviewResult.Success(it)
NetworkResult.success(it)
},
{
it.printStackTrace()
SearchPreviewResult.Failure(it)
NetworkResult.failure(it)
}
)
}

fun getTrendingStatusPager(): Flow<PagingData<StatusUiData>> =
Pager(
config = PagingConfig(
pageSize = 20,
enablePlaceholders = false,
),
pagingSourceFactory = {
TrendingPagingSource(api = api)
},
).flow

fun getPublicTimelinePager(): Flow<PagingData<StatusUiData>> =
Pager(
config = PagingConfig(
pageSize = 20,
enablePlaceholders = false,
),
pagingSourceFactory = {
PublicTimelinePagingSource(api = api)
},
).flow
}

sealed interface SearchPreviewResult {
data class Success(val response: SearchResult?) : SearchPreviewResult
data class Failure(val exception: Throwable) : SearchPreviewResult
suspend fun getNews(): NetworkResult<List<News>> = api.trendingNews(10)
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
package com.github.whitescent.mastify.domain

import android.content.ClipData
import android.content.ClipboardManager
import android.content.Context
import com.github.whitescent.mastify.network.MastodonApi
import com.github.whitescent.mastify.ui.component.status.StatusSnackbarType
Expand All @@ -33,8 +34,7 @@ class StatusActionHandler(private val api: MastodonApi) {
val snackBarFlow = snackBarChanel.receiveAsFlow()

suspend fun onStatusAction(action: StatusAction, context: Context) {
val clipManager =
context.getSystemService(Context.CLIPBOARD_SERVICE) as android.content.ClipboardManager
val clipManager = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
when (action) {
is StatusAction.Favorite -> {
if (action.favorite) api.favouriteStatus(action.id) else api.unfavouriteStatus(action.id)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,9 @@ fun Status.toUiData(): StatusUiData = StatusUiData(
favouritesCount = reblog?.favouritesCount ?: favouritesCount,
favorited = reblog?.favorited ?: favorited,
inReplyToId = reblog?.inReplyToId ?: inReplyToId,
// NOTE: make sure that you need to do a conversion whenever you use this property,
// otherwise it may cause inconsistencies between StatusUiData and StatusUiData.actionable
actionable = actionableStatus,
actionableId = actionableStatus.id,
hasUnloadedStatus = hasUnloadedStatus
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ class InstanceSwitchAuthInterceptor(private val db: AppDatabase) : Interceptor {
} else {
runBlocking {
val currentAccount = db.accountDao().getActiveAccount()
logcat { "currentAccount $currentAccount" }
if (currentAccount != null) {
val accessToken = currentAccount.accessToken
if (accessToken.isNotEmpty()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import com.github.whitescent.mastify.network.model.search.SearchResult
import com.github.whitescent.mastify.network.model.status.NewStatus
import com.github.whitescent.mastify.network.model.status.Status
import com.github.whitescent.mastify.network.model.status.StatusContext
import com.github.whitescent.mastify.network.model.trends.News
import retrofit2.Response
import retrofit2.http.Body
import retrofit2.http.Field
Expand Down Expand Up @@ -96,6 +97,12 @@ interface MastodonApi {
@Query("offset") offset: Int = 0
): Response<List<Status>>

@GET("api/v1/trends/links")
suspend fun trendingNews(
@Query("limit") limit: Int? = null,
@Query("offset") offset: Int = 0
): NetworkResult<List<News>>

@POST("api/v1/statuses/{id}/bookmark")
suspend fun bookmarkStatus(
@Path("id") statusId: String,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,9 @@ package com.github.whitescent.mastify.network.model.status
import kotlinx.serialization.Serializable

@Serializable
data class Hashtag(val name: String, val url: String, val following: Boolean? = null)
data class Hashtag(
val name: String,
val url: String,
val following: Boolean?,
val history: List<History>?
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* Copyright 2023 WhiteScent
*
* This file is a part of Mastify.
*
* This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation; either version 3 of the
* License, or (at your option) any later version.
*
* Mastify is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along with Mastify; if not,
* see <http://www.gnu.org/licenses>.
*/

package com.github.whitescent.mastify.network.model.status

import kotlinx.serialization.Serializable

@Serializable
data class History(
val day: String,
val uses: String,
val accounts: String
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* Copyright 2023 WhiteScent
*
* This file is a part of Mastify.
*
* This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation; either version 3 of the
* License, or (at your option) any later version.
*
* Mastify is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along with Mastify; if not,
* see <http://www.gnu.org/licenses>.
*/

package com.github.whitescent.mastify.network.model.trends

import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
data class News(
val url: String,
val title: String,
val description: String,
@SerialName("author_name") val authorname: String,
@SerialName("provider_name") val providername: String,
@SerialName("published_at") val publishedAt: String?,
val image: String,
val blurhash: String
)
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@

package com.github.whitescent.mastify.paging

import com.github.whitescent.mastify.paging.LoadState.Error
import com.github.whitescent.mastify.paging.LoadState.NotLoading

class Paginator<Key, Item>(
private val refreshKey: Key,
private inline val getAppendKey: suspend () -> Key,
Expand All @@ -25,7 +28,12 @@ class Paginator<Key, Item>(
private inline val onRequest: suspend (Key) -> Result<List<Item>>,
private inline val onSuccess: suspend (loadState: LoadState, items: List<Item>) -> Unit,
) : PaginatorInterface<Key, Item> {
private var loadState = LoadState.NotLoading

var loadState = NotLoading
private set

var endReached: Boolean = false
private set

override suspend fun append() {
if (loadState == LoadState.Append) return
Expand All @@ -35,16 +43,17 @@ class Paginator<Key, Item>(
val appendKey = getAppendKey()
val result = onRequest(appendKey).getOrElse {
onError(it)
loadState = LoadState.Error
loadState = Error
onLoadUpdated(loadState)
return
}
if (result.isEmpty()) endReached = true
onSuccess(loadState, result)
loadState = LoadState.NotLoading
loadState = NotLoading
onLoadUpdated(loadState)
} catch (e: Exception) {
onError(e)
loadState = LoadState.Error
loadState = Error
onLoadUpdated(loadState)
return
}
Expand All @@ -57,16 +66,17 @@ class Paginator<Key, Item>(
try {
val result = onRequest(refreshKey).getOrElse {
onError(it)
loadState = LoadState.Error
loadState = Error
onLoadUpdated(loadState)
return
}
if (result.isEmpty()) endReached = true
onSuccess(loadState, result)
loadState = LoadState.NotLoading
loadState = NotLoading
onLoadUpdated(loadState)
} catch (e: Exception) {
onError(e)
loadState = LoadState.Error
loadState = Error
onLoadUpdated(loadState)
return
}
Expand Down
Loading

0 comments on commit 51d069d

Please sign in to comment.