Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ import dev.dimension.flare.ui.component.status.status
import dev.dimension.flare.ui.model.UiProfile
import dev.dimension.flare.ui.model.UiSearchHistory
import dev.dimension.flare.ui.model.UiState
import dev.dimension.flare.ui.model.UiTimeline
import dev.dimension.flare.ui.model.UiTimelineV2
import dev.dimension.flare.ui.model.onSuccess
import dev.dimension.flare.ui.presenter.home.SearchHistoryPresenter
import dev.dimension.flare.ui.presenter.home.SearchHistoryState
Expand Down Expand Up @@ -166,7 +166,7 @@ private fun SearchContent(

internal fun LazyStaggeredGridScope.searchContent(
searchUsers: PagingState<UiProfile>,
searchStatus: PagingState<UiTimeline>,
searchStatus: PagingState<UiTimelineV2>,
toUser: (MicroBlogKey) -> Unit,
) {
searchUsers
Expand Down
22 changes: 22 additions & 0 deletions app/src/main/java/dev/dimension/flare/ui/route/Route.kt
Original file line number Diff line number Diff line change
Expand Up @@ -448,12 +448,24 @@ internal sealed interface Route : NavKey {
val userKey: MicroBlogKey,
) : Route

@Serializable
public data class UnblockUser(
val accountType: AccountType?,
val userKey: MicroBlogKey,
) : Route

@Serializable
public data class MuteUser(
val accountType: AccountType?,
val userKey: MicroBlogKey,
) : Route

@Serializable
public data class UnmuteUser(
val accountType: AccountType?,
val userKey: MicroBlogKey,
) : Route

@Serializable
public data class ReportUser(
val accountType: AccountType?,
Expand Down Expand Up @@ -625,6 +637,11 @@ internal sealed interface Route : NavKey {
accountType = deeplinkRoute.accountKey?.let { AccountType.Specific(it) },
userKey = deeplinkRoute.userKey,
)
is DeeplinkRoute.UnblockUser ->
Route.UnblockUser(
accountType = deeplinkRoute.accountKey?.let { AccountType.Specific(it) },
userKey = deeplinkRoute.userKey,
)
is DeeplinkRoute.DirectMessage ->
DM.UserConversation(
accountType = AccountType.Specific(deeplinkRoute.accountKey),
Expand All @@ -640,6 +657,11 @@ internal sealed interface Route : NavKey {
accountType = deeplinkRoute.accountKey?.let { AccountType.Specific(it) },
userKey = deeplinkRoute.userKey,
)
is DeeplinkRoute.UnmuteUser ->
Route.UnmuteUser(
accountType = deeplinkRoute.accountKey?.let { AccountType.Specific(it) },
userKey = deeplinkRoute.userKey,
)
is DeeplinkRoute.ReportUser ->
Route.ReportUser(
accountType = deeplinkRoute.accountKey?.let { AccountType.Specific(it) },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,14 +105,15 @@ import dev.dimension.flare.ui.component.status.CommonStatusComponent
import dev.dimension.flare.ui.component.status.StatusVisibilityComponent
import dev.dimension.flare.ui.model.UiEmoji
import dev.dimension.flare.ui.model.UiState
import dev.dimension.flare.ui.model.UiTimeline
import dev.dimension.flare.ui.model.UiTimelineV2
import dev.dimension.flare.ui.model.map
import dev.dimension.flare.ui.model.mapNotNull
import dev.dimension.flare.ui.model.onError
import dev.dimension.flare.ui.model.onSuccess
import dev.dimension.flare.ui.model.takeSuccess
import dev.dimension.flare.ui.presenter.compose.ComposePresenter
import dev.dimension.flare.ui.presenter.compose.ComposeStatus
import dev.dimension.flare.ui.presenter.home.ActiveAccountPresenter
import dev.dimension.flare.ui.presenter.invoke
import dev.dimension.flare.ui.theme.FlareTheme
import dev.dimension.flare.ui.theme.screenHorizontalPadding
Expand All @@ -132,20 +133,34 @@ fun ShortcutComposeRoute(
initialText: String = "",
initialMedias: ImmutableList<Uri> = persistentListOf(),
) {
val activeAccountState by producePresenter(key = "shortcut_compose_active_account") {
activeAccountPresenter()
}
val accountType =
activeAccountState.user
.takeSuccess()
?.let { AccountType.Specific(it.key) }
?: AccountType.Guest
FlareTheme {
CompositionLocalProvider(
LocalContentColor provides MaterialTheme.colorScheme.onBackground,
) {
ComposeScreen(
onBack = onBack,
accountType = AccountType.Active,
accountType = accountType,
initialText = initialText,
initialMedias = initialMedias,
)
}
}
}

@Composable
private fun activeAccountPresenter() =
run {
remember { ActiveAccountPresenter() }.invoke()
}

@OptIn(
ExperimentalMaterial3Api::class,
ExperimentalMaterial3ExpressiveApi::class,
Expand Down Expand Up @@ -255,7 +270,7 @@ internal fun ComposeScreen(
state.state.selectAccount(account)
},
label = {
Text(it.handle)
Text(it.handle.canonical)
},
leadingIcon = {
AvatarComponent(it.avatar, size = 24.dp)
Expand Down Expand Up @@ -285,7 +300,7 @@ internal fun ComposeScreen(
user.onSuccess { data ->
DropdownMenuItem(
text = {
Text(text = data.handle)
Text(text = data.handle.canonical)
},
onClick = {
state.state.selectAccount(account)
Expand Down Expand Up @@ -616,8 +631,8 @@ internal fun ComposeScreen(

state.state.replyState?.let { replyState ->
replyState.onSuccess { state ->
val content = state.content
if (content is UiTimeline.ItemContent.Status) {
val content = state as? UiTimelineV2.Post
if (content is UiTimelineV2.Post) {
Card {
CompositionLocalProvider(
LocalComponentAppearance provides
Expand Down Expand Up @@ -1062,7 +1077,7 @@ private fun composePresenter(
?.toString(),
visibility =
state.visibilityState.takeSuccess()?.visibility
?: UiTimeline.ItemContent.Status.TopEndContent.Visibility.Type.Public,
?: UiTimelineV2.Post.Visibility.Public,
account = it,
referenceStatus =
status?.let {
Expand Down Expand Up @@ -1286,40 +1301,40 @@ internal enum class PollExpiration(
Days7(R.string.compose_poll_expiration_7_days, 7.days),
}

internal val UiTimeline.ItemContent.Status.TopEndContent.Visibility.Type.localName: Int
internal val UiTimelineV2.Post.Visibility.localName: Int
get() =
when (this) {
UiTimeline.ItemContent.Status.TopEndContent.Visibility.Type.Public ->
UiTimelineV2.Post.Visibility.Public ->
R.string.misskey_visibility_public

UiTimeline.ItemContent.Status.TopEndContent.Visibility.Type.Home ->
UiTimelineV2.Post.Visibility.Home ->
R.string.misskey_visibility_home

UiTimeline.ItemContent.Status.TopEndContent.Visibility.Type.Followers ->
UiTimelineV2.Post.Visibility.Followers ->
R.string.misskey_visibility_followers

UiTimeline.ItemContent.Status.TopEndContent.Visibility.Type.Specified ->
UiTimelineV2.Post.Visibility.Specified ->
R.string.misskey_visibility_specified

UiTimeline.ItemContent.Status.TopEndContent.Visibility.Type.Channel ->
UiTimelineV2.Post.Visibility.Channel ->
R.string.misskey_visibility_public
}

internal val UiTimeline.ItemContent.Status.TopEndContent.Visibility.Type.localDescription: Int
internal val UiTimelineV2.Post.Visibility.localDescription: Int
get() =
when (this) {
UiTimeline.ItemContent.Status.TopEndContent.Visibility.Type.Public ->
UiTimelineV2.Post.Visibility.Public ->
R.string.misskey_visibility_public_description

UiTimeline.ItemContent.Status.TopEndContent.Visibility.Type.Home ->
UiTimelineV2.Post.Visibility.Home ->
R.string.misskey_visibility_home_description

UiTimeline.ItemContent.Status.TopEndContent.Visibility.Type.Followers ->
UiTimelineV2.Post.Visibility.Followers ->
R.string.misskey_visibility_followers_description

UiTimeline.ItemContent.Status.TopEndContent.Visibility.Type.Specified ->
UiTimelineV2.Post.Visibility.Specified ->
R.string.misskey_visibility_specified_description

UiTimeline.ItemContent.Status.TopEndContent.Visibility.Type.Channel ->
UiTimelineV2.Post.Visibility.Channel ->
R.string.misskey_visibility_public_description
}
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ internal fun DiscoverScreen(onUserClick: (AccountType, MicroBlogKey) -> Unit) {
state.setAccount(profile)
},
label = {
Text(profile.handle)
Text(profile.handle.canonical)
},
leadingIcon = {
AvatarComponent(
Expand Down
17 changes: 13 additions & 4 deletions app/src/main/java/dev/dimension/flare/ui/screen/home/HomeScreen.kt
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ import dev.dimension.flare.ui.model.onLoading
import dev.dimension.flare.ui.model.onSuccess
import dev.dimension.flare.ui.model.takeSuccess
import dev.dimension.flare.ui.presenter.HomeTabsPresenter
import dev.dimension.flare.ui.presenter.home.ActiveAccountPresenter
import dev.dimension.flare.ui.presenter.home.AllNotificationBadgePresenter
import dev.dimension.flare.ui.presenter.home.UserPresenter
import dev.dimension.flare.ui.presenter.invoke
Expand Down Expand Up @@ -136,7 +137,7 @@ internal fun HomeScreen(afterInit: () -> Unit) {
}

val currentRoute = topLevelBackStack.topLevelKey
val accountType = currentRoute.accountTypeOr(AccountType.Active)
val accountType = currentRoute.accountTypeOr(state.defaultAccountType)
val userState by producePresenter(key = "home_account_type_$accountType") {
userPresenter(accountType)
}
Expand Down Expand Up @@ -167,6 +168,7 @@ internal fun HomeScreen(afterInit: () -> Unit) {
userState,
layoutType,
currentRoute,
state.defaultAccountType,
navigate,
)
},
Expand Down Expand Up @@ -314,6 +316,7 @@ private fun HomeRailHeader(
userState: UiState<UiProfile>,
layoutType: NavigationSuiteType,
currentRoute: Route,
defaultAccountType: AccountType,
navigate: (Route) -> Unit,
) {
val scope = rememberCoroutineScope()
Expand Down Expand Up @@ -418,7 +421,7 @@ private fun HomeRailHeader(
textStyle = MaterialTheme.typography.titleMedium,
)
Text(
user.handle,
user.handle.canonical,
style = MaterialTheme.typography.bodySmall,
color = MaterialTheme.colorScheme.outline,
)
Expand Down Expand Up @@ -456,7 +459,7 @@ private fun HomeRailHeader(
navigate(
Route.Compose.New(
currentRoute.accountTypeOr(
AccountType.Active,
defaultAccountType,
),
),
)
Expand Down Expand Up @@ -484,7 +487,7 @@ private fun HomeRailHeader(
navigate(
Route.Compose.New(
currentRoute.accountTypeOr(
AccountType.Active,
defaultAccountType,
),
),
)
Expand Down Expand Up @@ -542,6 +545,7 @@ private fun getDirection(
@Composable
private fun presenter() =
run {
val activeAccountState = remember { ActiveAccountPresenter() }.invoke()
val navigationState =
remember {
NavigationState()
Expand All @@ -563,6 +567,11 @@ private fun presenter() =
val tabs = tabs.tabs
val navigationState = navigationState
val scrollToTopRegistry = scrollToTopRegistry
val defaultAccountType: AccountType =
activeAccountState.user
.takeSuccess()
?.let { AccountType.Specific(it.key) }
?: AccountType.Guest
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,9 @@ internal fun NotificationScreen() {
},
minTabWidth = 48.dp,
) {
state.notifications.forEach { (account, badge) ->
state.notifications.forEach { item ->
val account = item.profile
val badge = item.badge
LeadingIconTab(
modifier = Modifier.clip(CircleShape),
selectedContentColor = MaterialTheme.colorScheme.onSecondaryContainer,
Expand All @@ -104,7 +106,7 @@ internal fun NotificationScreen() {
},
text = {
Text(
text = account.handle,
text = account.handle.canonical,
maxLines = 1,
)
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ internal fun SearchScreen(
state.searchState.setAccount(profile)
},
label = {
Text(profile.handle)
Text(profile.handle.canonical)
},
leadingIcon = {
AvatarComponent(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ import dev.dimension.flare.ui.component.status.CommonStatusComponent
import dev.dimension.flare.ui.humanizer.humanize
import dev.dimension.flare.ui.model.UiMedia
import dev.dimension.flare.ui.model.UiState
import dev.dimension.flare.ui.model.UiTimeline
import dev.dimension.flare.ui.model.UiTimelineV2
import dev.dimension.flare.ui.model.getFileName
import dev.dimension.flare.ui.model.isSuccess
import dev.dimension.flare.ui.model.onLoading
Expand Down Expand Up @@ -438,8 +438,8 @@ internal fun StatusMediaScreen(
}

state.status.onSuccess { status ->
val content = status.content
if (content is UiTimeline.ItemContent.Status) {
val content = status as? UiTimelineV2.Post
if (content is UiTimelineV2.Post) {
androidx.compose.animation.AnimatedVisibility(
visible = state.showUi,
modifier =
Expand Down Expand Up @@ -563,8 +563,8 @@ internal fun StatusMediaScreen(
contentColor = MaterialTheme.colorScheme.onSurface,
) {
state.status.onSuccess {
val content = it.content
if (content is UiTimeline.ItemContent.Status) {
val content = it as? UiTimelineV2.Post
if (content is UiTimelineV2.Post) {
CompositionLocalProvider(
LocalComponentAppearance provides
LocalComponentAppearance.current.copy(
Expand Down Expand Up @@ -866,7 +866,7 @@ private fun statusMediaPresenter(
.onSuccess {
medias =
UiState.Success(
(it.content as? UiTimeline.ItemContent.Status)
(it as? UiTimelineV2.Post)
?.images
.orEmpty()
.toImmutableList(),
Expand Down Expand Up @@ -904,11 +904,11 @@ private fun statusMediaPresenter(
}

fun save(data: UiMedia) {
val status = (state.status.takeSuccess()?.content as? UiTimeline.ItemContent.Status)
val status = (state.status.takeSuccess() as? UiTimelineV2.Post)
if (status != null) {
val statusKey = status.statusKey.toString()
val userHandle = status.user?.handle ?: "unknown"
val fileName = data.getFileName(statusKey, userHandle)
val statusKeyString = statusKey.toString()
val userHandle = status.user?.handle?.canonical ?: "unknown"
val fileName = data.getFileName(statusKeyString, userHandle)

when (data) {
is UiMedia.Audio -> download(data.url, fileName)
Expand Down
Loading