From 5439746ac29b316650d3d003619273119254c3da Mon Sep 17 00:00:00 2001
From: osamu <46447427+sam-osamu@users.noreply.github.com>
Date: Sun, 5 Nov 2023 13:55:07 +0900
Subject: [PATCH 1/6] =?UTF-8?q?=E3=83=81=E3=83=A3=E3=83=B3=E3=83=8D?=
=?UTF-8?q?=E3=83=AB=E3=81=AE=E3=83=AA=E3=83=8E=E3=83=BC=E3=83=88=EF=BC=8F?=
=?UTF-8?q?=E5=BC=95=E7=94=A8=E3=83=AA=E3=83=8E=E3=83=BC=E3=83=88=E3=81=8A?=
=?UTF-8?q?=E3=82=88=E3=81=B3=E3=83=AA=E3=83=8E=E3=83=BC=E3=83=88=E5=88=B6?=
=?UTF-8?q?=E9=99=90=E3=81=AE=E3=81=82=E3=82=8B=E3=83=81=E3=83=A3=E3=83=B3?=
=?UTF-8?q?=E3=83=8D=E3=83=AB=E3=81=AB=E5=AF=BE=E5=BF=9C?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../api/misskey/v12/channel/ChannelDTOTest.kt | 2 +-
.../model/channel/ChannelStateTest.kt | 3 +-
.../api/misskey/v12/channel/channels.kt | 7 +++-
.../src/main/res/values-ja/strings.xml | 2 ++
.../src/main/res/values-zh/strings.xml | 2 ++
.../src/main/res/values/strings.xml | 2 ++
.../note/impl/NoteApiAdapter.kt | 21 +++++++----
.../note/impl/NoteRepositoryImpl.kt | 4 +--
.../milktea/channel/ChannelCard.kt | 9 +++--
.../note/renote/RenoteBottomSheetDialog.kt | 18 +++++++---
.../milktea/note/renote/RenoteDialogLayout.kt | 36 +++++++++++++++----
.../milktea/note/renote/RenoteUiState.kt | 2 ++
.../note/renote/RenoteUiStateBuilder.kt | 14 ++++++--
.../milktea/note/renote/RenoteViewModel.kt | 21 ++++++++---
.../milktea/note/view/NoteActionHandler.kt | 18 +++++++---
.../milktea/note/viewmodel/NotesViewModel.kt | 6 ++--
.../milktea/note/viewmodel/QuoteRenoteData.kt | 8 +++++
.../milktea/model/channel/Channel.kt | 1 +
.../milktea/model/note/NoteRepository.kt | 2 +-
.../CreateRenoteMultipleAccountUseCase.kt | 15 +++++---
20 files changed, 147 insertions(+), 46 deletions(-)
create mode 100644 modules/features/note/src/main/java/net/pantasystem/milktea/note/viewmodel/QuoteRenoteData.kt
diff --git a/app/src/test/java/jp/panta/misskeyandroidclient/api/misskey/v12/channel/ChannelDTOTest.kt b/app/src/test/java/jp/panta/misskeyandroidclient/api/misskey/v12/channel/ChannelDTOTest.kt
index e2edec3c85..d31b66ec0c 100644
--- a/app/src/test/java/jp/panta/misskeyandroidclient/api/misskey/v12/channel/ChannelDTOTest.kt
+++ b/app/src/test/java/jp/panta/misskeyandroidclient/api/misskey/v12/channel/ChannelDTOTest.kt
@@ -49,7 +49,7 @@ class ChannelDTOTest {
assertEquals(channelDTO.isFollowing, channel.isFollowing)
assertEquals(channelDTO.hasUnreadNote, channel.hasUnreadNote)
assertEquals(channelDTO.name, channel.name)
-
+ assertEquals(channelDTO.allowRenoteToExternal, channel.allowRenoteToExternal)
}
@Test
diff --git a/app/src/test/java/jp/panta/misskeyandroidclient/model/channel/ChannelStateTest.kt b/app/src/test/java/jp/panta/misskeyandroidclient/model/channel/ChannelStateTest.kt
index a9c20e955a..a063ccc934 100644
--- a/app/src/test/java/jp/panta/misskeyandroidclient/model/channel/ChannelStateTest.kt
+++ b/app/src/test/java/jp/panta/misskeyandroidclient/model/channel/ChannelStateTest.kt
@@ -88,7 +88,8 @@ class ChannelStateTest {
lastNotedAt = null,
notesCount = 0,
usersCount = 0,
- userId = User.Id(id.accountId, "userId")
+ userId = User.Id(id.accountId, "userId"),
+ allowRenoteToExternal = true,
)
}
diff --git a/modules/api/src/main/java/net/pantasystem/milktea/api/misskey/v12/channel/channels.kt b/modules/api/src/main/java/net/pantasystem/milktea/api/misskey/v12/channel/channels.kt
index 3572eeb79a..6c89af1c1b 100644
--- a/modules/api/src/main/java/net/pantasystem/milktea/api/misskey/v12/channel/channels.kt
+++ b/modules/api/src/main/java/net/pantasystem/milktea/api/misskey/v12/channel/channels.kt
@@ -46,6 +46,10 @@ data class ChannelDTO(
@SerialName("isFollowing")
val isFollowing: Boolean? = null,
+
+ // この値が含まれていなかった時は合わせてtrueにする(本体側のDB定義側はデフォルト値がtrueになっている)
+ @SerialName("allowRenoteToExternal")
+ val allowRenoteToExternal: Boolean = true
) {
fun toModel(account: Account): Channel {
return Channel(
@@ -59,7 +63,8 @@ data class ChannelDTO(
usersCount = usersCount,
userId = userId?.let { User.Id(account.accountId, it) },
hasUnreadNote = hasUnreadNote,
- isFollowing = isFollowing
+ isFollowing = isFollowing,
+ allowRenoteToExternal = allowRenoteToExternal,
)
}
}
diff --git a/modules/common_resource/src/main/res/values-ja/strings.xml b/modules/common_resource/src/main/res/values-ja/strings.xml
index ff1e57ee45..893f1faad8 100644
--- a/modules/common_resource/src/main/res/values-ja/strings.xml
+++ b/modules/common_resource/src/main/res/values-ja/strings.xml
@@ -23,7 +23,9 @@
フォロー中
フォロワー
リポスト
+ チャンネル内にリポスト
引用
+ チャンネル内に引用
discovery
リポストしました
絵文字/カスタム絵文字を入力
diff --git a/modules/common_resource/src/main/res/values-zh/strings.xml b/modules/common_resource/src/main/res/values-zh/strings.xml
index 355b17b9da..d19a2a42b9 100644
--- a/modules/common_resource/src/main/res/values-zh/strings.xml
+++ b/modules/common_resource/src/main/res/values-zh/strings.xml
@@ -23,7 +23,9 @@
关注中
关注者
转发
+ 频道内转发
引用转发
+ 频道内引用转发
发现
转发
自定义表情
diff --git a/modules/common_resource/src/main/res/values/strings.xml b/modules/common_resource/src/main/res/values/strings.xml
index 3d189c82d9..c6cfbd68f6 100644
--- a/modules/common_resource/src/main/res/values/strings.xml
+++ b/modules/common_resource/src/main/res/values/strings.xml
@@ -23,7 +23,9 @@
Following
Followers
Renote
+ Renote in channel
Quote renote
+ Quote renote in channel
Discovery
Renote
Emoji
diff --git a/modules/data/src/main/java/net/pantasystem/milktea/data/infrastructure/note/impl/NoteApiAdapter.kt b/modules/data/src/main/java/net/pantasystem/milktea/data/infrastructure/note/impl/NoteApiAdapter.kt
index 1053bd7110..6a85258da6 100644
--- a/modules/data/src/main/java/net/pantasystem/milktea/data/infrastructure/note/impl/NoteApiAdapter.kt
+++ b/modules/data/src/main/java/net/pantasystem/milktea/data/infrastructure/note/impl/NoteApiAdapter.kt
@@ -43,7 +43,7 @@ interface NoteApiAdapter {
suspend fun delete(noteId: Note.Id): DeleteNoteResultType
suspend fun createThreadMute(noteId: Note.Id): ToggleThreadMuteResultType
suspend fun deleteThreadMute(noteId: Note.Id): ToggleThreadMuteResultType
- suspend fun renote(target: Note): RenoteResultType
+ suspend fun renote(target: Note, inChannel: Boolean): RenoteResultType
suspend fun vote(noteId: Note.Id, choice: Poll.Choice, target: Note)
@@ -59,9 +59,9 @@ internal class NoteApiAdapterFactoryImpl @Inject constructor(
private val uploader: FileUploaderProvider,
private val filePropertyDataSource: FilePropertyDataSource,
private val loggerFactory: Logger.Factory,
-): NoteApiAdapter.Factory {
+) : NoteApiAdapter.Factory {
override suspend fun create(account: Account): NoteApiAdapter {
- return when(account.instanceType) {
+ return when (account.instanceType) {
Account.InstanceType.MISSKEY, Account.InstanceType.FIREFISH -> NoteApiAdapterMisskeyPattern(
accountRepository = accountRepository,
misskeyAPIProvider = misskeyAPIProvider,
@@ -69,6 +69,7 @@ internal class NoteApiAdapterFactoryImpl @Inject constructor(
uploader = uploader,
loggerFactory = loggerFactory,
)
+
Account.InstanceType.MASTODON, Account.InstanceType.PLEROMA -> NoteApiAdapterMastodonPattern(
uploader = uploader,
mastodonAPIProvider = mastodonAPIProvider,
@@ -77,6 +78,7 @@ internal class NoteApiAdapterFactoryImpl @Inject constructor(
}
}
}
+
private class NoteApiAdapterMisskeyPattern(
val accountRepository: AccountRepository,
val misskeyAPIProvider: MisskeyAPIProvider,
@@ -150,11 +152,17 @@ private class NoteApiAdapterMisskeyPattern(
return ToggleThreadMuteResultType.Misskey
}
- override suspend fun renote(target: Note): RenoteResultType {
+ override suspend fun renote(target: Note, inChannel: Boolean): RenoteResultType {
val account = accountRepository.get(target.id.accountId).getOrThrow()
return create(
CreateNote(
- author = account, renoteId = target.id,
+ author = account,
+ renoteId = target.id,
+ channelId = if (inChannel) {
+ target.channelId
+ } else {
+ null
+ },
text = null,
visibility = target.visibility
)
@@ -212,6 +220,7 @@ private class NoteApiAdapterMastodonPattern(
uploader.get(createNote.author)
.upload(UploadSource.LocalFile(appFile), false).id
}
+
is AppFile.Remote -> appFile.id
}
}
@@ -275,7 +284,7 @@ private class NoteApiAdapterMastodonPattern(
return ToggleThreadMuteResultType.Mastodon(requireNotNull(body))
}
- override suspend fun renote(target: Note): RenoteResultType {
+ override suspend fun renote(target: Note, inChannel: Boolean): RenoteResultType {
val account = accountRepository.get(target.id.accountId).getOrThrow()
val toot = mastodonAPIProvider.get(account).reblog(target.id.noteId)
.throwIfHasError()
diff --git a/modules/data/src/main/java/net/pantasystem/milktea/data/infrastructure/note/impl/NoteRepositoryImpl.kt b/modules/data/src/main/java/net/pantasystem/milktea/data/infrastructure/note/impl/NoteRepositoryImpl.kt
index 61d9ede6ad..f095c8152e 100644
--- a/modules/data/src/main/java/net/pantasystem/milktea/data/infrastructure/note/impl/NoteRepositoryImpl.kt
+++ b/modules/data/src/main/java/net/pantasystem/milktea/data/infrastructure/note/impl/NoteRepositoryImpl.kt
@@ -41,11 +41,11 @@ class NoteRepositoryImpl @Inject constructor(
}
}
- override suspend fun renote(noteId: Note.Id): Result = runCancellableCatching {
+ override suspend fun renote(noteId: Note.Id, inChannel: Boolean): Result = runCancellableCatching {
withContext(ioDispatcher) {
val account = getAccount.get(noteId.accountId)
val n = find(noteId).getOrThrow()
- convertAndAdd(account, noteApiAdapterFactory.create(account).renote(n))
+ convertAndAdd(account, noteApiAdapterFactory.create(account).renote(n, inChannel))
}
}
diff --git a/modules/features/channel/src/main/java/net/pantasystem/milktea/channel/ChannelCard.kt b/modules/features/channel/src/main/java/net/pantasystem/milktea/channel/ChannelCard.kt
index 0a2a09ceae..acb1c61aad 100644
--- a/modules/features/channel/src/main/java/net/pantasystem/milktea/channel/ChannelCard.kt
+++ b/modules/features/channel/src/main/java/net/pantasystem/milktea/channel/ChannelCard.kt
@@ -225,7 +225,8 @@ fun PreviewChannelCard() {
userId = User.Id(0, "userId"),
usersCount = 4,
isFollowing = true,
- hasUnreadNote = true
+ hasUnreadNote = true,
+ allowRenoteToExternal = true,
),
isPaged = true,
)
@@ -243,7 +244,8 @@ fun PreviewChannelCard() {
userId = User.Id(0, "userId"),
usersCount = 4,
isFollowing = false,
- hasUnreadNote = false
+ hasUnreadNote = false,
+ allowRenoteToExternal = true,
), isPaged = false
)
}
@@ -260,7 +262,8 @@ fun PreviewChannelCard() {
userId = User.Id(0, "userId"),
usersCount = 4,
isFollowing = false,
- hasUnreadNote = false
+ hasUnreadNote = false,
+ allowRenoteToExternal = true,
), isPaged = false
)
}
diff --git a/modules/features/note/src/main/java/net/pantasystem/milktea/note/renote/RenoteBottomSheetDialog.kt b/modules/features/note/src/main/java/net/pantasystem/milktea/note/renote/RenoteBottomSheetDialog.kt
index 6908fe3a8a..d527c8bf81 100644
--- a/modules/features/note/src/main/java/net/pantasystem/milktea/note/renote/RenoteBottomSheetDialog.kt
+++ b/modules/features/note/src/main/java/net/pantasystem/milktea/note/renote/RenoteBottomSheetDialog.kt
@@ -65,7 +65,6 @@ class RenoteBottomSheetDialog : BottomSheetDialogFragment() {
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
-
return ComposeView(requireContext()).apply {
setContent {
MilkteaStyleConfigApplyAndTheme(configRepository = configRepository) {
@@ -81,14 +80,23 @@ class RenoteBottomSheetDialog : BottomSheetDialogFragment() {
viewModel.renote()
dismiss()
},
+ onQuoteRenoteButtonClicked = {
+ notesViewModel.showQuoteNoteEditor(noteId, false)
+ dismiss()
+ },
+ onRenoteInChannelButtonClicked = {
+ viewModel.renote(inChannel = true)
+ dismiss()
+ },
+ onQuoteInChannelRenoteButtonClicked = {
+ notesViewModel.showQuoteNoteEditor(noteId, true)
+ dismiss()
+ },
onDeleteRenoteButtonCLicked = {
viewModel.unRenote()
dismiss()
},
- onQuoteRenoteButtonClicked = {
- notesViewModel.showQuoteNoteEditor(noteId)
- dismiss()
- })
+ )
}
}
}
diff --git a/modules/features/note/src/main/java/net/pantasystem/milktea/note/renote/RenoteDialogLayout.kt b/modules/features/note/src/main/java/net/pantasystem/milktea/note/renote/RenoteDialogLayout.kt
index 1eea0c9c8e..888087cc11 100644
--- a/modules/features/note/src/main/java/net/pantasystem/milktea/note/renote/RenoteDialogLayout.kt
+++ b/modules/features/note/src/main/java/net/pantasystem/milktea/note/renote/RenoteDialogLayout.kt
@@ -19,6 +19,8 @@ fun RenoteDialogContent(
onToggleAddAccount: (Long) -> Unit,
onRenoteButtonClicked: () -> Unit,
onQuoteRenoteButtonClicked: () -> Unit,
+ onRenoteInChannelButtonClicked: () -> Unit,
+ onQuoteInChannelRenoteButtonClicked: () -> Unit,
onDeleteRenoteButtonCLicked: () -> Unit,
) {
Surface(
@@ -33,11 +35,14 @@ fun RenoteDialogContent(
accounts = uiState.accounts,
onClick = onToggleAddAccount
)
- NormalBottomSheetDialogSelectionLayout(
- onClick = onRenoteButtonClicked,
- icon = Icons.Default.Repeat,
- text = stringResource(id = R.string.renote)
- )
+
+ if (uiState.isRenoteButtonVisible) {
+ NormalBottomSheetDialogSelectionLayout(
+ onClick = onRenoteButtonClicked,
+ icon = Icons.Default.Repeat,
+ text = stringResource(id = R.string.renote)
+ )
+ }
Spacer(modifier = Modifier.height(8.dp))
if (isRenotedByMe) {
@@ -50,14 +55,31 @@ fun RenoteDialogContent(
}
-
- if (uiState.canQuote) {
+ if (uiState.isRenoteButtonVisible && uiState.canQuote) {
NormalBottomSheetDialogSelectionLayout(
onClick = onQuoteRenoteButtonClicked,
icon = Icons.Default.FormatQuote,
text = stringResource(id = R.string.quote_renote)
)
}
+
+ if (uiState.isChannelRenoteButtonVisible) {
+ Spacer(modifier = Modifier.height(8.dp))
+ NormalBottomSheetDialogSelectionLayout(
+ onClick = onRenoteInChannelButtonClicked,
+ icon = Icons.Default.Repeat,
+ text = stringResource(id = R.string.renote_in_channel)
+ )
+
+ if (uiState.canQuote) {
+ Spacer(modifier = Modifier.height(8.dp))
+ NormalBottomSheetDialogSelectionLayout(
+ onClick = onQuoteInChannelRenoteButtonClicked,
+ icon = Icons.Default.FormatQuote,
+ text = stringResource(id = R.string.quote_renote_in_channel)
+ )
+ }
+ }
}
}
}
\ No newline at end of file
diff --git a/modules/features/note/src/main/java/net/pantasystem/milktea/note/renote/RenoteUiState.kt b/modules/features/note/src/main/java/net/pantasystem/milktea/note/renote/RenoteUiState.kt
index 5b8566db4d..6da61c864a 100644
--- a/modules/features/note/src/main/java/net/pantasystem/milktea/note/renote/RenoteUiState.kt
+++ b/modules/features/note/src/main/java/net/pantasystem/milktea/note/renote/RenoteUiState.kt
@@ -13,6 +13,8 @@ data class RenoteViewModelUiState(
),
val accounts: List = emptyList(),
val canQuote: Boolean = true,
+ val isRenoteButtonVisible: Boolean = true,
+ val isChannelRenoteButtonVisible: Boolean = false,
)
data class RenoteViewModelTargetNoteState(
diff --git a/modules/features/note/src/main/java/net/pantasystem/milktea/note/renote/RenoteUiStateBuilder.kt b/modules/features/note/src/main/java/net/pantasystem/milktea/note/renote/RenoteUiStateBuilder.kt
index e7f6bf6b71..96e0dc1ee8 100644
--- a/modules/features/note/src/main/java/net/pantasystem/milktea/note/renote/RenoteUiStateBuilder.kt
+++ b/modules/features/note/src/main/java/net/pantasystem/milktea/note/renote/RenoteUiStateBuilder.kt
@@ -10,8 +10,10 @@ import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn
import net.pantasystem.milktea.common.ResultState
+import net.pantasystem.milktea.common.coroutines.combine
import net.pantasystem.milktea.common.initialState
import net.pantasystem.milktea.model.account.Account
+import net.pantasystem.milktea.model.channel.Channel
import net.pantasystem.milktea.model.instance.InstanceInfoService
import net.pantasystem.milktea.model.instance.InstanceInfoType
import net.pantasystem.milktea.model.note.Note
@@ -30,6 +32,7 @@ class RenoteUiStateBuilder @Inject constructor(
fun buildState(
targetNoteIdFlow: StateFlow,
noteFlow: Flow,
+ channelFlow: Flow,
noteSyncState: Flow>,
selectedAccountIds: Flow>,
accountsFlow: Flow>,
@@ -106,17 +109,24 @@ class RenoteUiStateBuilder @Inject constructor(
emptyList()
)
+ val isRenoteButtonVisibleFlow = channelFlow.map { it?.allowRenoteToExternal ?: true }
+ val isChannelRenoteButtonVisibleFlow = channelFlow.map { it != null }
+
return combine(
targetNoteIdFlow,
noteState,
accountWithUsers,
currentAccountInstanceInfo,
- ) { noteId, syncState, accounts, instanceInfo ->
+ isRenoteButtonVisibleFlow,
+ isChannelRenoteButtonVisibleFlow,
+ ) { noteId, syncState, accounts, instanceInfo, isRenoteButtonVisible, isChannelRenoteButtonVisible ->
RenoteViewModelUiState(
targetNoteId = noteId,
noteState = syncState,
accounts = accounts,
- canQuote = instanceInfo?.canQuote ?: false
+ canQuote = instanceInfo?.canQuote ?: false,
+ isRenoteButtonVisible = isRenoteButtonVisible,
+ isChannelRenoteButtonVisible = isChannelRenoteButtonVisible,
)
}
}
diff --git a/modules/features/note/src/main/java/net/pantasystem/milktea/note/renote/RenoteViewModel.kt b/modules/features/note/src/main/java/net/pantasystem/milktea/note/renote/RenoteViewModel.kt
index c3dd531abc..f9f0b7cf8e 100644
--- a/modules/features/note/src/main/java/net/pantasystem/milktea/note/renote/RenoteViewModel.kt
+++ b/modules/features/note/src/main/java/net/pantasystem/milktea/note/renote/RenoteViewModel.kt
@@ -13,6 +13,7 @@ import net.pantasystem.milktea.common.ResultState
import net.pantasystem.milktea.common.asLoadingStateFlow
import net.pantasystem.milktea.common.initialState
import net.pantasystem.milktea.model.account.AccountRepository
+import net.pantasystem.milktea.model.channel.ChannelRepository
import net.pantasystem.milktea.model.instance.InstanceInfoService
import net.pantasystem.milktea.model.note.*
import net.pantasystem.milktea.model.note.repost.CreateRenoteMultipleAccountUseCase
@@ -25,6 +26,7 @@ class RenoteViewModel @Inject constructor(
val noteRepository: NoteRepository,
val accountRepository: AccountRepository,
val userRepository: UserRepository,
+ private val channelRepository: ChannelRepository,
val accountStore: AccountStore,
val userDataSource: UserDataSource,
val renoteUseCase: CreateRenoteMultipleAccountUseCase,
@@ -38,7 +40,6 @@ class RenoteViewModel @Inject constructor(
private var _targetNoteId = MutableStateFlow(null)
-
private val _resultEvents = MutableSharedFlow(
onBufferOverflow = BufferOverflow.DROP_OLDEST,
extraBufferCapacity = 20
@@ -58,6 +59,16 @@ class RenoteViewModel @Inject constructor(
null
)
+ @OptIn(ExperimentalCoroutinesApi::class)
+ val channel = note.filterNotNull()
+ .mapNotNull { it.note.channelId }
+ .flatMapLatest { flowOf(channelRepository.findOne(it).getOrNull()) }
+ .stateIn(
+ viewModelScope,
+ SharingStarted.WhileSubscribed(5_000),
+ null
+ )
+
private val _selectedAccountIds = MutableStateFlow>(emptyList())
private val accounts = accountStore.observeAccounts.stateIn(
viewModelScope,
@@ -90,6 +101,7 @@ class RenoteViewModel @Inject constructor(
val uiState = renoteUiStateBuilder.buildState(
targetNoteIdFlow = _targetNoteId,
noteFlow = note,
+ channelFlow = channel,
noteSyncState = _syncState,
selectedAccountIds = _selectedAccountIds,
accountsFlow = accounts,
@@ -123,12 +135,11 @@ class RenoteViewModel @Inject constructor(
}
}
- fun renote() {
- val noteId = _targetNoteId.value
- ?: return
+ fun renote(inChannel: Boolean = false) {
+ val noteId = _targetNoteId.value ?: return
val accountIds = _selectedAccountIds.value
viewModelScope.launch {
- val result = renoteUseCase(noteId, accountIds)
+ val result = renoteUseCase(noteId, accountIds, inChannel)
_resultEvents.tryEmit(
RenoteActionResultEvent.Renote(result, noteId, accountIds)
)
diff --git a/modules/features/note/src/main/java/net/pantasystem/milktea/note/view/NoteActionHandler.kt b/modules/features/note/src/main/java/net/pantasystem/milktea/note/view/NoteActionHandler.kt
index 81c291f99a..6baefef934 100644
--- a/modules/features/note/src/main/java/net/pantasystem/milktea/note/view/NoteActionHandler.kt
+++ b/modules/features/note/src/main/java/net/pantasystem/milktea/note/view/NoteActionHandler.kt
@@ -31,10 +31,20 @@ class NoteActionHandler(
}.flowWithLifecycle(lifecycleOwner.lifecycle, Lifecycle.State.RESUMED)
.launchIn(lifecycleOwner.lifecycleScope)
- notesViewModel.quoteRenoteTarget.onEach {
- val intent = NoteEditorActivity.newBundle(context, quoteTo = it.id)
- context.startActivity(intent)
- }.flowWithLifecycle(lifecycleOwner.lifecycle, Lifecycle.State.RESUMED)
+ notesViewModel.quoteRenoteTarget
+ .onEach {
+ val intent = NoteEditorActivity.newBundle(
+ context,
+ quoteTo = it.note.id,
+ channelId = if (it.isRenoteToChannel) {
+ it.note.channelId
+ } else {
+ null
+ }
+ )
+ context.startActivity(intent)
+ }
+ .flowWithLifecycle(lifecycleOwner.lifecycle, Lifecycle.State.RESUMED)
.launchIn(lifecycleOwner.lifecycleScope)
notesViewModel.openNoteEditorEvent.filterNotNull().onEach { note ->
diff --git a/modules/features/note/src/main/java/net/pantasystem/milktea/note/viewmodel/NotesViewModel.kt b/modules/features/note/src/main/java/net/pantasystem/milktea/note/viewmodel/NotesViewModel.kt
index ec4cea701b..caf99bad00 100644
--- a/modules/features/note/src/main/java/net/pantasystem/milktea/note/viewmodel/NotesViewModel.kt
+++ b/modules/features/note/src/main/java/net/pantasystem/milktea/note/viewmodel/NotesViewModel.kt
@@ -55,7 +55,7 @@ class NotesViewModel @Inject constructor(
private val _statusMessage = MutableSharedFlow(onBufferOverflow = BufferOverflow.DROP_OLDEST, extraBufferCapacity = 10)
val statusMessage = _statusMessage.asSharedFlow()
- val quoteRenoteTarget = MutableSharedFlow(onBufferOverflow = BufferOverflow.DROP_OLDEST, extraBufferCapacity = 10)
+ val quoteRenoteTarget = MutableSharedFlow(onBufferOverflow = BufferOverflow.DROP_OLDEST, extraBufferCapacity = 10)
val confirmDeletionEvent = MutableSharedFlow(onBufferOverflow = BufferOverflow.DROP_OLDEST, extraBufferCapacity = 10)
@@ -66,11 +66,11 @@ class NotesViewModel @Inject constructor(
private val _openNoteEditorEvent = MutableSharedFlow(onBufferOverflow = BufferOverflow.DROP_OLDEST, extraBufferCapacity = 10)
val openNoteEditorEvent = _openNoteEditorEvent.asSharedFlow()
- fun showQuoteNoteEditor(noteId: Note.Id) {
+ fun showQuoteNoteEditor(noteId: Note.Id, isRenoteToChannel: Boolean) {
viewModelScope.launch {
recursiveSearchHasContentNote(noteId).onSuccess { note ->
withContext(Dispatchers.Main) {
- quoteRenoteTarget.tryEmit(note)
+ quoteRenoteTarget.tryEmit(QuoteRenoteData(note, isRenoteToChannel))
}
}
diff --git a/modules/features/note/src/main/java/net/pantasystem/milktea/note/viewmodel/QuoteRenoteData.kt b/modules/features/note/src/main/java/net/pantasystem/milktea/note/viewmodel/QuoteRenoteData.kt
new file mode 100644
index 0000000000..236425bb1f
--- /dev/null
+++ b/modules/features/note/src/main/java/net/pantasystem/milktea/note/viewmodel/QuoteRenoteData.kt
@@ -0,0 +1,8 @@
+package net.pantasystem.milktea.note.viewmodel
+
+import net.pantasystem.milktea.model.note.Note
+
+data class QuoteRenoteData(
+ val note: Note,
+ val isRenoteToChannel: Boolean,
+)
\ No newline at end of file
diff --git a/modules/model/src/main/java/net/pantasystem/milktea/model/channel/Channel.kt b/modules/model/src/main/java/net/pantasystem/milktea/model/channel/Channel.kt
index 1d7f932a92..c53be3ab8d 100644
--- a/modules/model/src/main/java/net/pantasystem/milktea/model/channel/Channel.kt
+++ b/modules/model/src/main/java/net/pantasystem/milktea/model/channel/Channel.kt
@@ -21,6 +21,7 @@ data class Channel(
val userId: User.Id?,
val isFollowing: Boolean?,
val hasUnreadNote: Boolean?,
+ val allowRenoteToExternal: Boolean,
) {
companion object;
diff --git a/modules/model/src/main/java/net/pantasystem/milktea/model/note/NoteRepository.kt b/modules/model/src/main/java/net/pantasystem/milktea/model/note/NoteRepository.kt
index b023df767c..9f1dd78fa5 100644
--- a/modules/model/src/main/java/net/pantasystem/milktea/model/note/NoteRepository.kt
+++ b/modules/model/src/main/java/net/pantasystem/milktea/model/note/NoteRepository.kt
@@ -9,7 +9,7 @@ interface NoteRepository {
suspend fun create(createNote: CreateNote): Result
- suspend fun renote(noteId: Note.Id): Result
+ suspend fun renote(noteId: Note.Id, inChannel: Boolean): Result
suspend fun unrenote(noteId: Note.Id): Result
diff --git a/modules/model/src/main/java/net/pantasystem/milktea/model/note/repost/CreateRenoteMultipleAccountUseCase.kt b/modules/model/src/main/java/net/pantasystem/milktea/model/note/repost/CreateRenoteMultipleAccountUseCase.kt
index 23bed7517d..1beabdc33b 100644
--- a/modules/model/src/main/java/net/pantasystem/milktea/model/note/repost/CreateRenoteMultipleAccountUseCase.kt
+++ b/modules/model/src/main/java/net/pantasystem/milktea/model/note/repost/CreateRenoteMultipleAccountUseCase.kt
@@ -21,6 +21,7 @@ class CreateRenoteMultipleAccountUseCase @Inject constructor(
suspend operator fun invoke(
noteId: Note.Id,
accountIds: List,
+ inChannel: Boolean,
): Result>> = runCancellableCatching {
coroutineScope {
val accounts = accountIds.map {
@@ -28,12 +29,16 @@ class CreateRenoteMultipleAccountUseCase @Inject constructor(
}
val note = recursiveSearchHasContentNote(noteId).getOrThrow()
accounts.map {
- resolveAndRenote(note, it.accountId)
+ resolveAndRenote(note, it.accountId, inChannel)
}
}
}
- private suspend fun resolveAndRenote(sourceNote: Note, accountId: Long): Result =
+ private suspend fun resolveAndRenote(
+ sourceNote: Note,
+ accountId: Long,
+ inChannel: Boolean,
+ ): Result =
runCancellableCatching {
val account = accountRepository.get(accountId).getOrThrow()
val relatedSourceNoteAccount =
@@ -44,17 +49,17 @@ class CreateRenoteMultipleAccountUseCase @Inject constructor(
noteRepository.find(Note.Id(account.accountId, sourceNote.id.noteId)).getOrThrow()
}
- renote(relatedNote).getOrThrow()
+ renote(relatedNote, inChannel).getOrThrow()
}
- private suspend fun renote(note: Note): Result =
+ private suspend fun renote(note: Note, inChannel: Boolean): Result =
runCancellableCatching {
if (checkCanRepostService
.canRepost(note.id)
.getOrElse { false }
) {
- noteRepository.renote(note.id).getOrThrow()
+ noteRepository.renote(note.id, inChannel).getOrThrow()
} else {
throw IllegalArgumentException()
}
From 4a91ad7f7a80d28d2dbdfba889e1b4f8f468eb2e Mon Sep 17 00:00:00 2001
From: osamu <46447427+sam-osamu@users.noreply.github.com>
Date: Sun, 5 Nov 2023 14:18:44 +0900
Subject: [PATCH 2/6] fix buildError
---
.../milktea/data/infrastructure/note/impl/NoteApiAdapter.kt | 1 -
1 file changed, 1 deletion(-)
diff --git a/modules/data/src/main/java/net/pantasystem/milktea/data/infrastructure/note/impl/NoteApiAdapter.kt b/modules/data/src/main/java/net/pantasystem/milktea/data/infrastructure/note/impl/NoteApiAdapter.kt
index a1b6073d9e..34f6d34662 100644
--- a/modules/data/src/main/java/net/pantasystem/milktea/data/infrastructure/note/impl/NoteApiAdapter.kt
+++ b/modules/data/src/main/java/net/pantasystem/milktea/data/infrastructure/note/impl/NoteApiAdapter.kt
@@ -165,7 +165,6 @@ private class NoteApiAdapterMisskeyPattern(
},
text = null,
visibility = target.visibility,
- channelId = target.channelId,
)
)
}
From 949bcb3d2505971edb800ea038563411235cf6bd Mon Sep 17 00:00:00 2001
From: osamu <46447427+sam-osamu@users.noreply.github.com>
Date: Sun, 5 Nov 2023 16:37:46 +0900
Subject: [PATCH 3/6] =?UTF-8?q?=E4=B8=80=E5=BA=A6=E3=83=81=E3=83=A3?=
=?UTF-8?q?=E3=83=B3=E3=83=8D=E3=83=AB=E5=86=85=E3=81=A7=E3=83=AA=E3=83=8E?=
=?UTF-8?q?=E3=83=BC=E3=83=88=E3=81=97=E3=82=88=E3=81=86=E3=81=A8=E3=81=99?=
=?UTF-8?q?=E3=82=8B=E3=81=A8=E3=80=81=E3=81=9D=E3=81=AE=E3=81=A8=E3=81=8D?=
=?UTF-8?q?=E3=81=AE=E9=81=B8=E6=8A=9E=E5=8F=AF=E5=90=A6=E7=8A=B6=E6=85=8B?=
=?UTF-8?q?=E3=81=8C=E6=AE=8B=E3=82=8B=E3=81=AE=E3=82=92=E4=BF=AE=E6=AD=A3?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../milktea/note/renote/RenoteViewModel.kt | 23 ++++++++++---------
1 file changed, 12 insertions(+), 11 deletions(-)
diff --git a/modules/features/note/src/main/java/net/pantasystem/milktea/note/renote/RenoteViewModel.kt b/modules/features/note/src/main/java/net/pantasystem/milktea/note/renote/RenoteViewModel.kt
index f9f0b7cf8e..b4daa656c6 100644
--- a/modules/features/note/src/main/java/net/pantasystem/milktea/note/renote/RenoteViewModel.kt
+++ b/modules/features/note/src/main/java/net/pantasystem/milktea/note/renote/RenoteViewModel.kt
@@ -38,7 +38,14 @@ class RenoteViewModel @Inject constructor(
val logger = loggerFactory.create("RenoteDialogViewModel")
- private var _targetNoteId = MutableStateFlow(null)
+ private val _targetNoteId = MutableStateFlow(null)
+
+ @OptIn(ExperimentalCoroutinesApi::class)
+ private val _targetNote = _targetNoteId.filterNotNull().flatMapLatest {
+ noteRepository.observeOne(it).filterNotNull().map { note ->
+ noteRelationGetter.get(note).getOrNull()
+ }
+ }
private val _resultEvents = MutableSharedFlow(
onBufferOverflow = BufferOverflow.DROP_OLDEST,
@@ -47,22 +54,16 @@ class RenoteViewModel @Inject constructor(
val resultEvents = _resultEvents.asSharedFlow()
-
- @OptIn(ExperimentalCoroutinesApi::class)
- val note = _targetNoteId.filterNotNull().flatMapLatest {
- noteRepository.observeOne(it).filterNotNull().map { note ->
- noteRelationGetter.get(note).getOrNull()
- }
- }.stateIn(
+ val note = _targetNote.stateIn(
viewModelScope,
SharingStarted.WhileSubscribed(5_000),
null
)
@OptIn(ExperimentalCoroutinesApi::class)
- val channel = note.filterNotNull()
- .mapNotNull { it.note.channelId }
- .flatMapLatest { flowOf(channelRepository.findOne(it).getOrNull()) }
+ val channel = note
+ .map { it?.note?.channelId }
+ .flatMapLatest { flowOf(it?.let { ch -> channelRepository.findOne(ch).getOrNull() }) }
.stateIn(
viewModelScope,
SharingStarted.WhileSubscribed(5_000),
From 2e54020bce895cf83ebfb1025a75485985067fc6 Mon Sep 17 00:00:00 2001
From: osamu <46447427+sam-osamu@users.noreply.github.com>
Date: Mon, 6 Nov 2023 09:01:44 +0900
Subject: [PATCH 4/6] =?UTF-8?q?withContext=E3=81=AE=E5=89=8A=E9=99=A4?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../pantasystem/milktea/note/viewmodel/NotesViewModel.kt | 7 +------
1 file changed, 1 insertion(+), 6 deletions(-)
diff --git a/modules/features/note/src/main/java/net/pantasystem/milktea/note/viewmodel/NotesViewModel.kt b/modules/features/note/src/main/java/net/pantasystem/milktea/note/viewmodel/NotesViewModel.kt
index caf99bad00..9c4071cc2c 100644
--- a/modules/features/note/src/main/java/net/pantasystem/milktea/note/viewmodel/NotesViewModel.kt
+++ b/modules/features/note/src/main/java/net/pantasystem/milktea/note/viewmodel/NotesViewModel.kt
@@ -3,12 +3,10 @@ package net.pantasystem.milktea.note.viewmodel
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import dagger.hilt.android.lifecycle.HiltViewModel
-import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.channels.BufferOverflow
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.coroutines.launch
-import kotlinx.coroutines.withContext
import net.pantasystem.milktea.app_store.notes.NoteTranslationStore
import net.pantasystem.milktea.common.Logger
import net.pantasystem.milktea.common_android.resource.StringSource
@@ -69,11 +67,8 @@ class NotesViewModel @Inject constructor(
fun showQuoteNoteEditor(noteId: Note.Id, isRenoteToChannel: Boolean) {
viewModelScope.launch {
recursiveSearchHasContentNote(noteId).onSuccess { note ->
- withContext(Dispatchers.Main) {
- quoteRenoteTarget.tryEmit(QuoteRenoteData(note, isRenoteToChannel))
- }
+ quoteRenoteTarget.tryEmit(QuoteRenoteData(note, isRenoteToChannel))
}
-
}
}
From 3e908e49419d283637b6b7084fb22c7e8c049e74 Mon Sep 17 00:00:00 2001
From: osamu <46447427+sam-osamu@users.noreply.github.com>
Date: Mon, 6 Nov 2023 09:07:36 +0900
Subject: [PATCH 5/6] =?UTF-8?q?channel=E3=81=AEstate=E4=BD=9C=E6=88=90?=
=?UTF-8?q?=E6=96=B9=E6=B3=95=E5=A4=89=E6=9B=B4?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../net/pantasystem/milktea/note/renote/RenoteViewModel.kt | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/modules/features/note/src/main/java/net/pantasystem/milktea/note/renote/RenoteViewModel.kt b/modules/features/note/src/main/java/net/pantasystem/milktea/note/renote/RenoteViewModel.kt
index b4daa656c6..2bfa8169d1 100644
--- a/modules/features/note/src/main/java/net/pantasystem/milktea/note/renote/RenoteViewModel.kt
+++ b/modules/features/note/src/main/java/net/pantasystem/milktea/note/renote/RenoteViewModel.kt
@@ -60,10 +60,8 @@ class RenoteViewModel @Inject constructor(
null
)
- @OptIn(ExperimentalCoroutinesApi::class)
- val channel = note
- .map { it?.note?.channelId }
- .flatMapLatest { flowOf(it?.let { ch -> channelRepository.findOne(ch).getOrNull() }) }
+ val channel = _targetNote
+ .map { it?.note?.channelId?.let { id -> channelRepository.findOne(id).getOrNull() } }
.stateIn(
viewModelScope,
SharingStarted.WhileSubscribed(5_000),
From 1515ca9cbbd887789debd85462aeb813e1c58094 Mon Sep 17 00:00:00 2001
From: osamu <46447427+sam-osamu@users.noreply.github.com>
Date: Mon, 6 Nov 2023 14:53:11 +0900
Subject: [PATCH 6/6] =?UTF-8?q?=E3=83=AA=E3=83=8E=E3=83=BC=E3=83=88?=
=?UTF-8?q?=E6=99=82=E3=81=AE=E3=83=91=E3=83=A9=E3=83=A1=E3=83=BC=E3=82=BF?=
=?UTF-8?q?=E5=BC=95=E3=81=8D=E5=9B=9E=E3=81=97=E6=96=B9=E6=B3=95=E3=82=92?=
=?UTF-8?q?=E5=B0=82=E7=94=A8=E3=81=AE=E3=83=A2=E3=83=87=E3=83=AB=E3=82=AF?=
=?UTF-8?q?=E3=83=A9=E3=82=B9=E3=81=AB=E5=A4=89=E6=9B=B4?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../note/impl/NoteApiAdapter.kt | 24 ++---
.../note/impl/NoteRepositoryImpl.kt | 7 +-
.../note/renote/RenoteBottomSheetDialog.kt | 6 +-
.../milktea/note/renote/RenoteViewModel.kt | 17 +++-
.../milktea/note/view/NoteActionHandler.kt | 8 +-
.../milktea/note/viewmodel/NotesViewModel.kt | 21 +++-
.../milktea/note/viewmodel/QuoteRenoteData.kt | 8 --
.../milktea/model/note/NoteRepository.kt | 3 +-
.../milktea/model/note/repost/CreateRenote.kt | 35 +++++++
.../CreateRenoteMultipleAccountUseCase.kt | 97 ++++++++++++-------
.../model/note/repost/QuoteRenoteData.kt | 25 +++++
11 files changed, 175 insertions(+), 76 deletions(-)
delete mode 100644 modules/features/note/src/main/java/net/pantasystem/milktea/note/viewmodel/QuoteRenoteData.kt
create mode 100644 modules/model/src/main/java/net/pantasystem/milktea/model/note/repost/CreateRenote.kt
create mode 100644 modules/model/src/main/java/net/pantasystem/milktea/model/note/repost/QuoteRenoteData.kt
diff --git a/modules/data/src/main/java/net/pantasystem/milktea/data/infrastructure/note/impl/NoteApiAdapter.kt b/modules/data/src/main/java/net/pantasystem/milktea/data/infrastructure/note/impl/NoteApiAdapter.kt
index 34f6d34662..4487ab7f81 100644
--- a/modules/data/src/main/java/net/pantasystem/milktea/data/infrastructure/note/impl/NoteApiAdapter.kt
+++ b/modules/data/src/main/java/net/pantasystem/milktea/data/infrastructure/note/impl/NoteApiAdapter.kt
@@ -27,6 +27,7 @@ import net.pantasystem.milktea.model.note.CreateNote
import net.pantasystem.milktea.model.note.Note
import net.pantasystem.milktea.model.note.NoteState
import net.pantasystem.milktea.model.note.poll.Poll
+import net.pantasystem.milktea.model.note.repost.CreateRenote
import net.pantasystem.milktea.model.note.type4Mastodon
import javax.inject.Inject
@@ -43,7 +44,7 @@ interface NoteApiAdapter {
suspend fun delete(noteId: Note.Id): DeleteNoteResultType
suspend fun createThreadMute(noteId: Note.Id): ToggleThreadMuteResultType
suspend fun deleteThreadMute(noteId: Note.Id): ToggleThreadMuteResultType
- suspend fun renote(target: Note, inChannel: Boolean): RenoteResultType
+ suspend fun renote(createRenote: CreateRenote): RenoteResultType
suspend fun vote(noteId: Note.Id, choice: Poll.Choice, target: Note)
@@ -152,19 +153,14 @@ private class NoteApiAdapterMisskeyPattern(
return ToggleThreadMuteResultType.Misskey
}
- override suspend fun renote(target: Note, inChannel: Boolean): RenoteResultType {
- val account = accountRepository.get(target.id.accountId).getOrThrow()
+ override suspend fun renote(createRenote: CreateRenote): RenoteResultType {
return create(
CreateNote(
- author = account,
- renoteId = target.id,
- channelId = if (inChannel) {
- target.channelId
- } else {
- null
- },
+ author = createRenote.author,
+ renoteId = createRenote.renoteId,
+ channelId = createRenote.channelId,
text = null,
- visibility = target.visibility,
+ visibility = createRenote.visibility,
)
)
}
@@ -284,9 +280,9 @@ private class NoteApiAdapterMastodonPattern(
return ToggleThreadMuteResultType.Mastodon(requireNotNull(body))
}
- override suspend fun renote(target: Note, inChannel: Boolean): RenoteResultType {
- val account = accountRepository.get(target.id.accountId).getOrThrow()
- val toot = mastodonAPIProvider.get(account).reblog(target.id.noteId)
+ override suspend fun renote(createRenote: CreateRenote): RenoteResultType {
+ val account = accountRepository.get(createRenote.author.accountId).getOrThrow()
+ val toot = mastodonAPIProvider.get(account).reblog(createRenote.renoteId.noteId)
.throwIfHasError()
.body()
return NoteResultType.Mastodon(requireNotNull(toot))
diff --git a/modules/data/src/main/java/net/pantasystem/milktea/data/infrastructure/note/impl/NoteRepositoryImpl.kt b/modules/data/src/main/java/net/pantasystem/milktea/data/infrastructure/note/impl/NoteRepositoryImpl.kt
index f095c8152e..46eb25be9c 100644
--- a/modules/data/src/main/java/net/pantasystem/milktea/data/infrastructure/note/impl/NoteRepositoryImpl.kt
+++ b/modules/data/src/main/java/net/pantasystem/milktea/data/infrastructure/note/impl/NoteRepositoryImpl.kt
@@ -23,6 +23,7 @@ import net.pantasystem.milktea.model.note.NoteResult
import net.pantasystem.milktea.model.note.NoteState
import net.pantasystem.milktea.model.note.NoteThreadContext
import net.pantasystem.milktea.model.note.poll.Poll
+import net.pantasystem.milktea.model.note.repost.CreateRenote
import javax.inject.Inject
class NoteRepositoryImpl @Inject constructor(
@@ -41,11 +42,9 @@ class NoteRepositoryImpl @Inject constructor(
}
}
- override suspend fun renote(noteId: Note.Id, inChannel: Boolean): Result = runCancellableCatching {
+ override suspend fun renote(createRenote: CreateRenote): Result = runCancellableCatching {
withContext(ioDispatcher) {
- val account = getAccount.get(noteId.accountId)
- val n = find(noteId).getOrThrow()
- convertAndAdd(account, noteApiAdapterFactory.create(account).renote(n, inChannel))
+ convertAndAdd(createRenote.author, noteApiAdapterFactory.create(createRenote.author).renote(createRenote))
}
}
diff --git a/modules/features/note/src/main/java/net/pantasystem/milktea/note/renote/RenoteBottomSheetDialog.kt b/modules/features/note/src/main/java/net/pantasystem/milktea/note/renote/RenoteBottomSheetDialog.kt
index d527c8bf81..04bf8ff965 100644
--- a/modules/features/note/src/main/java/net/pantasystem/milktea/note/renote/RenoteBottomSheetDialog.kt
+++ b/modules/features/note/src/main/java/net/pantasystem/milktea/note/renote/RenoteBottomSheetDialog.kt
@@ -81,15 +81,15 @@ class RenoteBottomSheetDialog : BottomSheetDialogFragment() {
dismiss()
},
onQuoteRenoteButtonClicked = {
- notesViewModel.showQuoteNoteEditor(noteId, false)
+ notesViewModel.showQuoteNoteEditor(noteId)
dismiss()
},
onRenoteInChannelButtonClicked = {
- viewModel.renote(inChannel = true)
+ viewModel.renoteToChannel()
dismiss()
},
onQuoteInChannelRenoteButtonClicked = {
- notesViewModel.showQuoteNoteEditor(noteId, true)
+ notesViewModel.showQuoteToChannelNoteEditor(noteId)
dismiss()
},
onDeleteRenoteButtonCLicked = {
diff --git a/modules/features/note/src/main/java/net/pantasystem/milktea/note/renote/RenoteViewModel.kt b/modules/features/note/src/main/java/net/pantasystem/milktea/note/renote/RenoteViewModel.kt
index 2bfa8169d1..055e8f47cd 100644
--- a/modules/features/note/src/main/java/net/pantasystem/milktea/note/renote/RenoteViewModel.kt
+++ b/modules/features/note/src/main/java/net/pantasystem/milktea/note/renote/RenoteViewModel.kt
@@ -29,7 +29,7 @@ class RenoteViewModel @Inject constructor(
private val channelRepository: ChannelRepository,
val accountStore: AccountStore,
val userDataSource: UserDataSource,
- val renoteUseCase: CreateRenoteMultipleAccountUseCase,
+ private val renoteUseCase: CreateRenoteMultipleAccountUseCase,
val noteRelationGetter: NoteRelationGetter,
private val instanceInfoService: InstanceInfoService,
renoteUiStateBuilder: RenoteUiStateBuilder,
@@ -134,11 +134,22 @@ class RenoteViewModel @Inject constructor(
}
}
- fun renote(inChannel: Boolean = false) {
+ fun renote() {
val noteId = _targetNoteId.value ?: return
val accountIds = _selectedAccountIds.value
viewModelScope.launch {
- val result = renoteUseCase(noteId, accountIds, inChannel)
+ val result = renoteUseCase.renote(noteId, accountIds)
+ _resultEvents.tryEmit(
+ RenoteActionResultEvent.Renote(result, noteId, accountIds)
+ )
+ }
+ }
+
+ fun renoteToChannel() {
+ val noteId = _targetNoteId.value ?: return
+ val accountIds = _selectedAccountIds.value
+ viewModelScope.launch {
+ val result = renoteUseCase.renoteToChannel(noteId, accountIds)
_resultEvents.tryEmit(
RenoteActionResultEvent.Renote(result, noteId, accountIds)
)
diff --git a/modules/features/note/src/main/java/net/pantasystem/milktea/note/view/NoteActionHandler.kt b/modules/features/note/src/main/java/net/pantasystem/milktea/note/view/NoteActionHandler.kt
index 6baefef934..fe8b4a679f 100644
--- a/modules/features/note/src/main/java/net/pantasystem/milktea/note/view/NoteActionHandler.kt
+++ b/modules/features/note/src/main/java/net/pantasystem/milktea/note/view/NoteActionHandler.kt
@@ -35,12 +35,8 @@ class NoteActionHandler(
.onEach {
val intent = NoteEditorActivity.newBundle(
context,
- quoteTo = it.note.id,
- channelId = if (it.isRenoteToChannel) {
- it.note.channelId
- } else {
- null
- }
+ quoteTo = it.noteId,
+ channelId = it.channelId
)
context.startActivity(intent)
}
diff --git a/modules/features/note/src/main/java/net/pantasystem/milktea/note/viewmodel/NotesViewModel.kt b/modules/features/note/src/main/java/net/pantasystem/milktea/note/viewmodel/NotesViewModel.kt
index 9c4071cc2c..eec6d7dc3a 100644
--- a/modules/features/note/src/main/java/net/pantasystem/milktea/note/viewmodel/NotesViewModel.kt
+++ b/modules/features/note/src/main/java/net/pantasystem/milktea/note/viewmodel/NotesViewModel.kt
@@ -25,6 +25,7 @@ import net.pantasystem.milktea.model.note.poll.Poll
import net.pantasystem.milktea.model.note.poll.VoteUseCase
import net.pantasystem.milktea.model.note.reaction.DeleteReactionsUseCase
import net.pantasystem.milktea.model.note.reaction.ToggleReactionUseCase
+import net.pantasystem.milktea.model.note.repost.QuoteRenoteData
import net.pantasystem.milktea.model.user.report.Report
import net.pantasystem.milktea.note.R
import javax.inject.Inject
@@ -64,10 +65,24 @@ class NotesViewModel @Inject constructor(
private val _openNoteEditorEvent = MutableSharedFlow(onBufferOverflow = BufferOverflow.DROP_OLDEST, extraBufferCapacity = 10)
val openNoteEditorEvent = _openNoteEditorEvent.asSharedFlow()
- fun showQuoteNoteEditor(noteId: Note.Id, isRenoteToChannel: Boolean) {
+ fun showQuoteNoteEditor(noteId: Note.Id) {
viewModelScope.launch {
- recursiveSearchHasContentNote(noteId).onSuccess { note ->
- quoteRenoteTarget.tryEmit(QuoteRenoteData(note, isRenoteToChannel))
+ // 引用リノートしようとしたノートが第三者によりリノートされたものである可能性もあるので、
+ // リノートIDを辿って大本のノートを探し出す
+ recursiveSearchHasContentNote(noteId).onSuccess {
+ quoteRenoteTarget.tryEmit(
+ QuoteRenoteData.ofTimeline(it.id)
+ )
+ }
+ }
+ }
+
+ fun showQuoteToChannelNoteEditor(noteId: Note.Id) {
+ viewModelScope.launch {
+ recursiveSearchHasContentNote(noteId).onSuccess {
+ quoteRenoteTarget.tryEmit(
+ QuoteRenoteData.ofChannel(it.id, requireNotNull(it.channelId))
+ )
}
}
}
diff --git a/modules/features/note/src/main/java/net/pantasystem/milktea/note/viewmodel/QuoteRenoteData.kt b/modules/features/note/src/main/java/net/pantasystem/milktea/note/viewmodel/QuoteRenoteData.kt
deleted file mode 100644
index 236425bb1f..0000000000
--- a/modules/features/note/src/main/java/net/pantasystem/milktea/note/viewmodel/QuoteRenoteData.kt
+++ /dev/null
@@ -1,8 +0,0 @@
-package net.pantasystem.milktea.note.viewmodel
-
-import net.pantasystem.milktea.model.note.Note
-
-data class QuoteRenoteData(
- val note: Note,
- val isRenoteToChannel: Boolean,
-)
\ No newline at end of file
diff --git a/modules/model/src/main/java/net/pantasystem/milktea/model/note/NoteRepository.kt b/modules/model/src/main/java/net/pantasystem/milktea/model/note/NoteRepository.kt
index 9f1dd78fa5..d38801a612 100644
--- a/modules/model/src/main/java/net/pantasystem/milktea/model/note/NoteRepository.kt
+++ b/modules/model/src/main/java/net/pantasystem/milktea/model/note/NoteRepository.kt
@@ -2,6 +2,7 @@ package net.pantasystem.milktea.model.note
import kotlinx.coroutines.flow.Flow
import net.pantasystem.milktea.model.note.poll.Poll
+import net.pantasystem.milktea.model.note.repost.CreateRenote
interface NoteRepository {
@@ -9,7 +10,7 @@ interface NoteRepository {
suspend fun create(createNote: CreateNote): Result
- suspend fun renote(noteId: Note.Id, inChannel: Boolean): Result
+ suspend fun renote(createRenote: CreateRenote): Result
suspend fun unrenote(noteId: Note.Id): Result
diff --git a/modules/model/src/main/java/net/pantasystem/milktea/model/note/repost/CreateRenote.kt b/modules/model/src/main/java/net/pantasystem/milktea/model/note/repost/CreateRenote.kt
new file mode 100644
index 0000000000..0300ab1433
--- /dev/null
+++ b/modules/model/src/main/java/net/pantasystem/milktea/model/note/repost/CreateRenote.kt
@@ -0,0 +1,35 @@
+package net.pantasystem.milktea.model.note.repost
+
+
+import net.pantasystem.milktea.model.account.Account
+import net.pantasystem.milktea.model.channel.Channel
+import net.pantasystem.milktea.model.note.Note
+import net.pantasystem.milktea.model.note.Visibility
+
+
+data class CreateRenote(
+ val author: Account,
+ val renoteId: Note.Id,
+ val channelId: Channel.Id?,
+ val visibility: Visibility,
+) {
+ companion object {
+ fun ofTimeline(author: Account, target: Note) : CreateRenote {
+ return CreateRenote(
+ author = author,
+ renoteId = target.id,
+ channelId = null,
+ visibility = target.visibility,
+ )
+ }
+
+ fun ofChannel(author: Account, target: Note): CreateRenote {
+ return CreateRenote(
+ author = author,
+ renoteId = target.id,
+ channelId = target.channelId,
+ visibility = target.visibility,
+ )
+ }
+ }
+}
\ No newline at end of file
diff --git a/modules/model/src/main/java/net/pantasystem/milktea/model/note/repost/CreateRenoteMultipleAccountUseCase.kt b/modules/model/src/main/java/net/pantasystem/milktea/model/note/repost/CreateRenoteMultipleAccountUseCase.kt
index 1beabdc33b..e83c73a6bf 100644
--- a/modules/model/src/main/java/net/pantasystem/milktea/model/note/repost/CreateRenoteMultipleAccountUseCase.kt
+++ b/modules/model/src/main/java/net/pantasystem/milktea/model/note/repost/CreateRenoteMultipleAccountUseCase.kt
@@ -3,6 +3,7 @@ package net.pantasystem.milktea.model.note.repost
import kotlinx.coroutines.coroutineScope
import net.pantasystem.milktea.common.runCancellableCatching
import net.pantasystem.milktea.model.UseCase
+import net.pantasystem.milktea.model.account.Account
import net.pantasystem.milktea.model.account.AccountRepository
import net.pantasystem.milktea.model.ap.ApResolverService
import net.pantasystem.milktea.model.note.Note
@@ -18,53 +19,81 @@ class CreateRenoteMultipleAccountUseCase @Inject constructor(
private val apResolverService: ApResolverService,
) : UseCase {
- suspend operator fun invoke(
- noteId: Note.Id,
- accountIds: List,
- inChannel: Boolean,
+ /**
+ * [targetNoteId]を持つノートをHTL/LTL/STL/GTLへリノートする。
+ * チャンネル内に投稿されたノートの場合、チャンネル内にはリノートされず各種TLへリノートされる。
+ * チャンネル内にリノートしたい場合は[renoteToChannel]を使用する。
+ *
+ * @param targetNoteId リノート対象の[Note.Id]
+ * @param publisherAccountIds このアカウントからリノートを行う
+ */
+ suspend fun renote(
+ targetNoteId: Note.Id,
+ publisherAccountIds: List,
): Result>> = runCancellableCatching {
coroutineScope {
- val accounts = accountIds.map {
- accountRepository.get(it).getOrThrow()
+ val note = recursiveSearchHasContentNote(targetNoteId).getOrThrow()
+ publisherAccountIds.map {
+ resolveAndRenote(note, it) { a, n ->
+ CreateRenote.ofTimeline(a, n)
+ }
}
- val note = recursiveSearchHasContentNote(noteId).getOrThrow()
- accounts.map {
- resolveAndRenote(note, it.accountId, inChannel)
+ }
+ }
+
+ /**
+ * [targetNoteId]を持つノートが投稿されたチャンネルと同じチャンネルにリノートする。
+ * [targetNoteId]がチャンネル外に投稿されたノートの場合、特定のチャンネル内にリノートということにはならず[renote]と同等の挙動となる。
+ * チャンネル外にリノートしたい場合は[renote]を使用する。
+ *
+ * @param targetNoteId リノート対象の[Note.Id]
+ * @param publisherAccountIds このアカウントからリノートを行う
+ */
+ suspend fun renoteToChannel(
+ targetNoteId: Note.Id,
+ publisherAccountIds: List,
+ ): Result>> = runCancellableCatching {
+ coroutineScope {
+ val note = recursiveSearchHasContentNote(targetNoteId).getOrThrow()
+ publisherAccountIds.map {
+ resolveAndRenote(note, it) { a, n ->
+ CreateRenote.ofChannel(a, n)
+ }
}
}
}
private suspend fun resolveAndRenote(
- sourceNote: Note,
- accountId: Long,
- inChannel: Boolean,
- ): Result =
- runCancellableCatching {
- val account = accountRepository.get(accountId).getOrThrow()
- val relatedSourceNoteAccount =
- accountRepository.get(sourceNote.id.accountId).getOrThrow()
- val relatedNote = if (account.getHost() != relatedSourceNoteAccount.getHost()) {
- apResolverService.resolve(sourceNote.id, accountId).getOrThrow()
- } else {
- noteRepository.find(Note.Id(account.accountId, sourceNote.id.noteId)).getOrThrow()
- }
+ targetNote: Note,
+ publisherAccountId: Long,
+ paramFactory: (Account, Note) -> CreateRenote
+ ): Result = runCancellableCatching {
+ val publisherAccount = accountRepository.get(publisherAccountId).getOrThrow()
+ val relatedTargetNoteAccount = accountRepository.get(targetNote.id.accountId).getOrThrow()
- renote(relatedNote, inChannel).getOrThrow()
+ val resolvedNote = if (publisherAccount.getHost() != relatedTargetNoteAccount.getHost()) {
+ // リノート発信アカウントと対象ノートのホストが異なる場合、
+ // AP経由でリノート発信アカウントのあるホストに対象ノートを取り寄せ、ホストに複製されたノートをリノートする
+ apResolverService
+ .resolve(targetNote.id, publisherAccountId)
+ .getOrThrow()
+ } else {
+ noteRepository
+ .find(Note.Id(publisherAccount.accountId, targetNote.id.noteId))
+ .getOrThrow()
}
-
- private suspend fun renote(note: Note, inChannel: Boolean): Result =
- runCancellableCatching {
- if (checkCanRepostService
- .canRepost(note.id)
- .getOrElse { false }
- ) {
- noteRepository.renote(note.id, inChannel).getOrThrow()
- } else {
- throw IllegalArgumentException()
- }
+ if (!checkCanRepostService.canRepost(resolvedNote.id).getOrElse { false }) {
+ throw IllegalArgumentException()
}
+ val resolvedAccount = accountRepository.get(resolvedNote.id.accountId).getOrThrow()
+
+ noteRepository
+ .renote(paramFactory.invoke(resolvedAccount, resolvedNote))
+ .getOrThrow()
+ }
+
private suspend fun recursiveSearchHasContentNote(noteId: Note.Id): Result =
runCancellableCatching {
val note = noteRepository.find(noteId).getOrThrow()
diff --git a/modules/model/src/main/java/net/pantasystem/milktea/model/note/repost/QuoteRenoteData.kt b/modules/model/src/main/java/net/pantasystem/milktea/model/note/repost/QuoteRenoteData.kt
new file mode 100644
index 0000000000..1aa2117dce
--- /dev/null
+++ b/modules/model/src/main/java/net/pantasystem/milktea/model/note/repost/QuoteRenoteData.kt
@@ -0,0 +1,25 @@
+package net.pantasystem.milktea.model.note.repost
+
+import net.pantasystem.milktea.model.channel.Channel
+import net.pantasystem.milktea.model.note.Note
+
+data class QuoteRenoteData(
+ val noteId: Note.Id,
+ val channelId: Channel.Id?,
+) {
+ companion object {
+ fun ofTimeline(noteId: Note.Id): QuoteRenoteData {
+ return QuoteRenoteData(
+ noteId = noteId,
+ channelId = null,
+ )
+ }
+
+ fun ofChannel(noteId: Note.Id, channelId: Channel.Id): QuoteRenoteData {
+ return QuoteRenoteData(
+ noteId = noteId,
+ channelId = channelId,
+ )
+ }
+ }
+}
\ No newline at end of file