fix: Disable "Scheduled post" support on GoToSocial accounts (#1025)
GoToSocial servers don't support scheduled posts; they return the wrong type, and this can cause a loop of posting. The GoToSocial bug to implement scheduled posts is https://github.com/superseriousbusiness/gotosocial/issues/1006. Fix this by adding a new server capability for scheduled post support, using it for most servers, and disabling it for GoToSocial. If scheduled post support is not available for an account: - The "Scheduled posts" menu option is not shown. - The scheduling button (clock) when composing a post is hidden, so the user cannot set scheduling parameters. Fixes #963
This commit is contained in:
parent
8fac5c3d4d
commit
c8aa4fd374
|
@ -81,9 +81,11 @@ import app.pachli.core.common.util.unsafeLazy
|
||||||
import app.pachli.core.data.repository.Lists
|
import app.pachli.core.data.repository.Lists
|
||||||
import app.pachli.core.data.repository.ListsRepository
|
import app.pachli.core.data.repository.ListsRepository
|
||||||
import app.pachli.core.data.repository.ListsRepository.Companion.compareByListTitle
|
import app.pachli.core.data.repository.ListsRepository.Companion.compareByListTitle
|
||||||
|
import app.pachli.core.data.repository.ServerRepository
|
||||||
import app.pachli.core.database.model.AccountEntity
|
import app.pachli.core.database.model.AccountEntity
|
||||||
import app.pachli.core.designsystem.EmbeddedFontFamily
|
import app.pachli.core.designsystem.EmbeddedFontFamily
|
||||||
import app.pachli.core.designsystem.R as DR
|
import app.pachli.core.designsystem.R as DR
|
||||||
|
import app.pachli.core.model.ServerOperation
|
||||||
import app.pachli.core.model.Timeline
|
import app.pachli.core.model.Timeline
|
||||||
import app.pachli.core.navigation.AboutActivityIntent
|
import app.pachli.core.navigation.AboutActivityIntent
|
||||||
import app.pachli.core.navigation.AccountActivityIntent
|
import app.pachli.core.navigation.AccountActivityIntent
|
||||||
|
@ -160,12 +162,15 @@ import com.mikepenz.materialdrawer.model.interfaces.nameRes
|
||||||
import com.mikepenz.materialdrawer.model.interfaces.nameText
|
import com.mikepenz.materialdrawer.model.interfaces.nameText
|
||||||
import com.mikepenz.materialdrawer.util.AbstractDrawerImageLoader
|
import com.mikepenz.materialdrawer.util.AbstractDrawerImageLoader
|
||||||
import com.mikepenz.materialdrawer.util.DrawerImageLoader
|
import com.mikepenz.materialdrawer.util.DrawerImageLoader
|
||||||
|
import com.mikepenz.materialdrawer.util.addItemAtPosition
|
||||||
import com.mikepenz.materialdrawer.util.addItems
|
import com.mikepenz.materialdrawer.util.addItems
|
||||||
import com.mikepenz.materialdrawer.util.addItemsAtPosition
|
import com.mikepenz.materialdrawer.util.addItemsAtPosition
|
||||||
|
import com.mikepenz.materialdrawer.util.getPosition
|
||||||
import com.mikepenz.materialdrawer.util.updateBadge
|
import com.mikepenz.materialdrawer.util.updateBadge
|
||||||
import com.mikepenz.materialdrawer.widget.AccountHeaderView
|
import com.mikepenz.materialdrawer.widget.AccountHeaderView
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
import de.c1710.filemojicompat_ui.helpers.EMOJI_PREFERENCE
|
import de.c1710.filemojicompat_ui.helpers.EMOJI_PREFERENCE
|
||||||
|
import io.github.z4kn4fein.semver.constraints.toConstraint
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import kotlin.math.max
|
import kotlin.math.max
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
@ -205,6 +210,9 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, MenuProvider {
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var androidNotificationsAreEnabled: AndroidNotificationsAreEnabledUseCase
|
lateinit var androidNotificationsAreEnabled: AndroidNotificationsAreEnabledUseCase
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
lateinit var serverRepository: ServerRepository
|
||||||
|
|
||||||
private val binding by viewBinding(ActivityMainBinding::inflate)
|
private val binding by viewBinding(ActivityMainBinding::inflate)
|
||||||
|
|
||||||
override val actionButton by unsafeLazy { binding.composeButton }
|
override val actionButton by unsafeLazy { binding.composeButton }
|
||||||
|
@ -402,6 +410,12 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, MenuProvider {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lifecycleScope.launch {
|
||||||
|
serverRepository.flow.collect {
|
||||||
|
refreshMainDrawerItems(intent.pachliAccountId, addSearchButton = hideTopToolbar)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
selectedEmojiPack = sharedPreferencesRepository.getString(EMOJI_PREFERENCE, "")
|
selectedEmojiPack = sharedPreferencesRepository.getString(EMOJI_PREFERENCE, "")
|
||||||
|
|
||||||
onBackPressedDispatcher.addCallback(this, onBackPressedCallback)
|
onBackPressedDispatcher.addCallback(this, onBackPressedCallback)
|
||||||
|
@ -749,6 +763,7 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, MenuProvider {
|
||||||
},
|
},
|
||||||
DividerDrawerItem(),
|
DividerDrawerItem(),
|
||||||
primaryDrawerItem {
|
primaryDrawerItem {
|
||||||
|
identifier = DRAWER_ITEM_DRAFTS
|
||||||
nameRes = R.string.action_access_drafts
|
nameRes = R.string.action_access_drafts
|
||||||
iconRes = R.drawable.ic_notebook
|
iconRes = R.drawable.ic_notebook
|
||||||
onClick = {
|
onClick = {
|
||||||
|
@ -757,15 +772,6 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, MenuProvider {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
primaryDrawerItem {
|
|
||||||
nameRes = R.string.action_access_scheduled_posts
|
|
||||||
iconRes = R.drawable.ic_access_time
|
|
||||||
onClick = {
|
|
||||||
startActivityWithDefaultTransition(
|
|
||||||
ScheduledStatusActivityIntent(context, pachliAccountId),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
primaryDrawerItem {
|
primaryDrawerItem {
|
||||||
identifier = DRAWER_ITEM_ANNOUNCEMENTS
|
identifier = DRAWER_ITEM_ANNOUNCEMENTS
|
||||||
nameRes = R.string.title_announcements
|
nameRes = R.string.title_announcements
|
||||||
|
@ -840,6 +846,23 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, MenuProvider {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If the server supports scheduled posts then add a "Scheduled posts" item
|
||||||
|
// after the "Drafts" item.
|
||||||
|
if (serverRepository.flow.replayCache.lastOrNull()?.get()?.can(ServerOperation.ORG_JOINMASTODON_STATUSES_SCHEDULED, ">= 1.0.0".toConstraint()) == true) {
|
||||||
|
binding.mainDrawer.addItemAtPosition(
|
||||||
|
binding.mainDrawer.getPosition(DRAWER_ITEM_DRAFTS) + 1,
|
||||||
|
primaryDrawerItem {
|
||||||
|
nameRes = R.string.action_access_scheduled_posts
|
||||||
|
iconRes = R.drawable.ic_access_time
|
||||||
|
onClick = {
|
||||||
|
startActivityWithDefaultTransition(
|
||||||
|
ScheduledStatusActivityIntent(binding.mainDrawer.context, pachliAccountId),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
if (BuildConfig.DEBUG) {
|
if (BuildConfig.DEBUG) {
|
||||||
// Add a "Developer tools" entry. Code that makes it easier to
|
// Add a "Developer tools" entry. Code that makes it easier to
|
||||||
// set the app state at runtime belongs here, it will never
|
// set the app state at runtime belongs here, it will never
|
||||||
|
@ -1260,6 +1283,9 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, MenuProvider {
|
||||||
|
|
||||||
/** Drawer identifier for the "Lists" section header. */
|
/** Drawer identifier for the "Lists" section header. */
|
||||||
private const val DRAWER_ITEM_LISTS: Long = 15
|
private const val DRAWER_ITEM_LISTS: Long = 15
|
||||||
|
|
||||||
|
/** Drawer identifier for the "Drafts" item. */
|
||||||
|
private const val DRAWER_ITEM_DRAFTS = 16L
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -505,6 +505,15 @@ class ComposeActivity :
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Hide the "Schedule" button if the server can't schedule. Simply
|
||||||
|
// disabling it could be confusing to users wondering why they can't
|
||||||
|
// use it.
|
||||||
|
lifecycleScope.launch {
|
||||||
|
viewModel.serverCanSchedule.collect {
|
||||||
|
binding.composeScheduleButton.visible(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
lifecycleScope.launch {
|
lifecycleScope.launch {
|
||||||
viewModel.media.combine(viewModel.poll) { media, poll ->
|
viewModel.media.combine(viewModel.poll) { media, poll ->
|
||||||
val active = poll == null &&
|
val active = poll == null &&
|
||||||
|
|
|
@ -35,6 +35,8 @@ import app.pachli.core.common.string.mastodonLength
|
||||||
import app.pachli.core.common.string.randomAlphanumericString
|
import app.pachli.core.common.string.randomAlphanumericString
|
||||||
import app.pachli.core.data.repository.AccountManager
|
import app.pachli.core.data.repository.AccountManager
|
||||||
import app.pachli.core.data.repository.InstanceInfoRepository
|
import app.pachli.core.data.repository.InstanceInfoRepository
|
||||||
|
import app.pachli.core.data.repository.ServerRepository
|
||||||
|
import app.pachli.core.model.ServerOperation
|
||||||
import app.pachli.core.navigation.ComposeActivityIntent.ComposeOptions
|
import app.pachli.core.navigation.ComposeActivityIntent.ComposeOptions
|
||||||
import app.pachli.core.navigation.ComposeActivityIntent.ComposeOptions.ComposeKind
|
import app.pachli.core.navigation.ComposeActivityIntent.ComposeOptions.ComposeKind
|
||||||
import app.pachli.core.network.model.Attachment
|
import app.pachli.core.network.model.Attachment
|
||||||
|
@ -49,17 +51,22 @@ import at.connyduck.calladapter.networkresult.fold
|
||||||
import com.github.michaelbull.result.Err
|
import com.github.michaelbull.result.Err
|
||||||
import com.github.michaelbull.result.Ok
|
import com.github.michaelbull.result.Ok
|
||||||
import com.github.michaelbull.result.Result
|
import com.github.michaelbull.result.Result
|
||||||
|
import com.github.michaelbull.result.get
|
||||||
import com.github.michaelbull.result.getOrElse
|
import com.github.michaelbull.result.getOrElse
|
||||||
import com.github.michaelbull.result.mapBoth
|
import com.github.michaelbull.result.mapBoth
|
||||||
import com.github.michaelbull.result.mapError
|
import com.github.michaelbull.result.mapError
|
||||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
|
import io.github.z4kn4fein.semver.constraints.toConstraint
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.channels.BufferOverflow
|
import kotlinx.coroutines.channels.BufferOverflow
|
||||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
import kotlinx.coroutines.flow.SharingStarted
|
||||||
import kotlinx.coroutines.flow.asSharedFlow
|
import kotlinx.coroutines.flow.asSharedFlow
|
||||||
import kotlinx.coroutines.flow.asStateFlow
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
|
import kotlinx.coroutines.flow.map
|
||||||
|
import kotlinx.coroutines.flow.stateIn
|
||||||
import kotlinx.coroutines.flow.update
|
import kotlinx.coroutines.flow.update
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
|
@ -73,6 +80,7 @@ class ComposeViewModel @Inject constructor(
|
||||||
private val serviceClient: ServiceClient,
|
private val serviceClient: ServiceClient,
|
||||||
private val draftHelper: DraftHelper,
|
private val draftHelper: DraftHelper,
|
||||||
instanceInfoRepo: InstanceInfoRepository,
|
instanceInfoRepo: InstanceInfoRepository,
|
||||||
|
private val serverRepository: ServerRepository,
|
||||||
) : ViewModel() {
|
) : ViewModel() {
|
||||||
|
|
||||||
/** The current content */
|
/** The current content */
|
||||||
|
@ -140,6 +148,11 @@ class ComposeViewModel @Inject constructor(
|
||||||
private val _statusLength = MutableStateFlow(0)
|
private val _statusLength = MutableStateFlow(0)
|
||||||
val statusLength = _statusLength.asStateFlow()
|
val statusLength = _statusLength.asStateFlow()
|
||||||
|
|
||||||
|
/** Flow of whether or not the server can schedule posts. */
|
||||||
|
val serverCanSchedule = serverRepository.flow.map {
|
||||||
|
it.get()?.can(ServerOperation.ORG_JOINMASTODON_STATUSES_SCHEDULED, ">= 1.0.0".toConstraint()) == true
|
||||||
|
}.stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), false)
|
||||||
|
|
||||||
private lateinit var composeKind: ComposeKind
|
private lateinit var composeKind: ComposeKind
|
||||||
|
|
||||||
// Used in ComposeActivity to pass state to result function when cropImage contract inflight
|
// Used in ComposeActivity to pass state to result function when cropImage contract inflight
|
||||||
|
|
|
@ -77,4 +77,13 @@ enum class ServerOperation(id: String, versions: List<Version>) {
|
||||||
ORG_JOINMASTODON_SEARCH_QUERY_IN_LIBRARY("org.joinmastodon.search.query:in:library", listOf(Version(major = 1))),
|
ORG_JOINMASTODON_SEARCH_QUERY_IN_LIBRARY("org.joinmastodon.search.query:in:library", listOf(Version(major = 1))),
|
||||||
ORG_JOINMASTODON_SEARCH_QUERY_IN_PUBLIC("org.joinmastodon.search.query:in:public", listOf(Version(major = 1))),
|
ORG_JOINMASTODON_SEARCH_QUERY_IN_PUBLIC("org.joinmastodon.search.query:in:public", listOf(Version(major = 1))),
|
||||||
ORG_JOINMASTODON_SEARCH_QUERY_BY_DATE("org.joinmastodon.search.query:in:public", listOf(Version(major = 1))),
|
ORG_JOINMASTODON_SEARCH_QUERY_BY_DATE("org.joinmastodon.search.query:in:public", listOf(Version(major = 1))),
|
||||||
|
|
||||||
|
/** Post a status with a `scheduled_at` property, and edit scheduled statuses. */
|
||||||
|
ORG_JOINMASTODON_STATUSES_SCHEDULED(
|
||||||
|
"org.joinmastodon.statuses.scheduled",
|
||||||
|
listOf(
|
||||||
|
// Initial introduction in Mastodon 2.7.0.
|
||||||
|
Version(major = 1),
|
||||||
|
),
|
||||||
|
),
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,6 +52,7 @@ import app.pachli.core.model.ServerOperation.ORG_JOINMASTODON_SEARCH_QUERY_IN_PU
|
||||||
import app.pachli.core.model.ServerOperation.ORG_JOINMASTODON_SEARCH_QUERY_IS_REPLY
|
import app.pachli.core.model.ServerOperation.ORG_JOINMASTODON_SEARCH_QUERY_IS_REPLY
|
||||||
import app.pachli.core.model.ServerOperation.ORG_JOINMASTODON_SEARCH_QUERY_IS_SENSITIVE
|
import app.pachli.core.model.ServerOperation.ORG_JOINMASTODON_SEARCH_QUERY_IS_SENSITIVE
|
||||||
import app.pachli.core.model.ServerOperation.ORG_JOINMASTODON_SEARCH_QUERY_LANGUAGE
|
import app.pachli.core.model.ServerOperation.ORG_JOINMASTODON_SEARCH_QUERY_LANGUAGE
|
||||||
|
import app.pachli.core.model.ServerOperation.ORG_JOINMASTODON_STATUSES_SCHEDULED
|
||||||
import app.pachli.core.model.ServerOperation.ORG_JOINMASTODON_STATUSES_TRANSLATE
|
import app.pachli.core.model.ServerOperation.ORG_JOINMASTODON_STATUSES_TRANSLATE
|
||||||
import app.pachli.core.network.Server.Error.UnparseableVersion
|
import app.pachli.core.network.Server.Error.UnparseableVersion
|
||||||
import app.pachli.core.network.model.InstanceV1
|
import app.pachli.core.network.model.InstanceV1
|
||||||
|
@ -241,6 +242,11 @@ data class Server(
|
||||||
when (kind) {
|
when (kind) {
|
||||||
// Glitch has the same version number as upstream Mastodon
|
// Glitch has the same version number as upstream Mastodon
|
||||||
GLITCH, MASTODON -> {
|
GLITCH, MASTODON -> {
|
||||||
|
// Scheduled statuses
|
||||||
|
when {
|
||||||
|
v >= "2.7.0".toVersion() -> c[ORG_JOINMASTODON_STATUSES_SCHEDULED] = "1.0.0".toVersion()
|
||||||
|
}
|
||||||
|
|
||||||
// Client filtering
|
// Client filtering
|
||||||
when {
|
when {
|
||||||
v >= "3.1.0".toVersion() -> c[ORG_JOINMASTODON_FILTERS_CLIENT] = "1.1.0".toVersion()
|
v >= "3.1.0".toVersion() -> c[ORG_JOINMASTODON_FILTERS_CLIENT] = "1.1.0".toVersion()
|
||||||
|
@ -281,6 +287,8 @@ data class Server(
|
||||||
}
|
}
|
||||||
|
|
||||||
GOTOSOCIAL -> {
|
GOTOSOCIAL -> {
|
||||||
|
// Can't do scheduled posts, https://github.com/superseriousbusiness/gotosocial/issues/1006
|
||||||
|
|
||||||
// Filters
|
// Filters
|
||||||
when {
|
when {
|
||||||
// Implemented in https://github.com/superseriousbusiness/gotosocial/pull/2936
|
// Implemented in https://github.com/superseriousbusiness/gotosocial/pull/2936
|
||||||
|
@ -305,12 +313,18 @@ data class Server(
|
||||||
FIREFISH -> { }
|
FIREFISH -> { }
|
||||||
|
|
||||||
// Sharkey can't filter, https://activitypub.software/TransFem-org/Sharkey/-/issues/492
|
// Sharkey can't filter, https://activitypub.software/TransFem-org/Sharkey/-/issues/492
|
||||||
SHARKEY -> { }
|
SHARKEY -> {
|
||||||
|
// Assume scheduled support (may be wrong).
|
||||||
|
c[ORG_JOINMASTODON_STATUSES_SCHEDULED] = "1.0.0".toVersion()
|
||||||
|
}
|
||||||
|
|
||||||
FRIENDICA -> {
|
FRIENDICA -> {
|
||||||
// Assume filter support (may be wrong)
|
// Assume filter support (may be wrong).
|
||||||
c[ORG_JOINMASTODON_FILTERS_SERVER] = "1.0.0".toVersion()
|
c[ORG_JOINMASTODON_FILTERS_SERVER] = "1.0.0".toVersion()
|
||||||
|
|
||||||
|
// Assume scheduled support (may be wrong).
|
||||||
|
c[ORG_JOINMASTODON_STATUSES_SCHEDULED] = "1.0.0".toVersion()
|
||||||
|
|
||||||
// Search
|
// Search
|
||||||
when {
|
when {
|
||||||
// Friendica has a number of search operators that are not in Mastodon.
|
// Friendica has a number of search operators that are not in Mastodon.
|
||||||
|
@ -323,10 +337,16 @@ data class Server(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Everything else. Assume server side filtering and no translation. This may be an
|
// Everything else. Assume:
|
||||||
// incorrect assumption.
|
//
|
||||||
|
// - server side filtering
|
||||||
|
// - scheduled status support
|
||||||
|
// - no translation
|
||||||
|
//
|
||||||
|
// This may be an incorrect assumption.
|
||||||
AKKOMA, FEDIBIRD, HOMETOWN, ICESHRIMP, PIXELFED, PLEROMA, UNKNOWN -> {
|
AKKOMA, FEDIBIRD, HOMETOWN, ICESHRIMP, PIXELFED, PLEROMA, UNKNOWN -> {
|
||||||
c[ORG_JOINMASTODON_FILTERS_SERVER] = "1.0.0".toVersion()
|
c[ORG_JOINMASTODON_FILTERS_SERVER] = "1.0.0".toVersion()
|
||||||
|
c[ORG_JOINMASTODON_STATUSES_SCHEDULED] = "1.0.0".toVersion()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return c
|
return c
|
||||||
|
|
|
@ -41,6 +41,7 @@ import app.pachli.core.model.ServerOperation.ORG_JOINMASTODON_SEARCH_QUERY_IN_LI
|
||||||
import app.pachli.core.model.ServerOperation.ORG_JOINMASTODON_SEARCH_QUERY_IS_REPLY
|
import app.pachli.core.model.ServerOperation.ORG_JOINMASTODON_SEARCH_QUERY_IS_REPLY
|
||||||
import app.pachli.core.model.ServerOperation.ORG_JOINMASTODON_SEARCH_QUERY_IS_SENSITIVE
|
import app.pachli.core.model.ServerOperation.ORG_JOINMASTODON_SEARCH_QUERY_IS_SENSITIVE
|
||||||
import app.pachli.core.model.ServerOperation.ORG_JOINMASTODON_SEARCH_QUERY_LANGUAGE
|
import app.pachli.core.model.ServerOperation.ORG_JOINMASTODON_SEARCH_QUERY_LANGUAGE
|
||||||
|
import app.pachli.core.model.ServerOperation.ORG_JOINMASTODON_STATUSES_SCHEDULED
|
||||||
import app.pachli.core.model.ServerOperation.ORG_JOINMASTODON_STATUSES_TRANSLATE
|
import app.pachli.core.model.ServerOperation.ORG_JOINMASTODON_STATUSES_TRANSLATE
|
||||||
import app.pachli.core.network.model.Account
|
import app.pachli.core.network.model.Account
|
||||||
import app.pachli.core.network.model.Configuration
|
import app.pachli.core.network.model.Configuration
|
||||||
|
@ -148,6 +149,7 @@ class ServerTest(
|
||||||
ORG_JOINMASTODON_FILTERS_CLIENT to "1.1.0".toVersion(),
|
ORG_JOINMASTODON_FILTERS_CLIENT to "1.1.0".toVersion(),
|
||||||
ORG_JOINMASTODON_FILTERS_SERVER to "1.0.0".toVersion(),
|
ORG_JOINMASTODON_FILTERS_SERVER to "1.0.0".toVersion(),
|
||||||
ORG_JOINMASTODON_SEARCH_QUERY_FROM to "1.0.0".toVersion(),
|
ORG_JOINMASTODON_SEARCH_QUERY_FROM to "1.0.0".toVersion(),
|
||||||
|
ORG_JOINMASTODON_STATUSES_SCHEDULED to "1.0.0".toVersion(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -170,6 +172,7 @@ class ServerTest(
|
||||||
ORG_JOINMASTODON_FILTERS_CLIENT to "1.1.0".toVersion(),
|
ORG_JOINMASTODON_FILTERS_CLIENT to "1.1.0".toVersion(),
|
||||||
ORG_JOINMASTODON_FILTERS_SERVER to "1.0.0".toVersion(),
|
ORG_JOINMASTODON_FILTERS_SERVER to "1.0.0".toVersion(),
|
||||||
ORG_JOINMASTODON_SEARCH_QUERY_FROM to "1.0.0".toVersion(),
|
ORG_JOINMASTODON_SEARCH_QUERY_FROM to "1.0.0".toVersion(),
|
||||||
|
ORG_JOINMASTODON_STATUSES_SCHEDULED to "1.0.0".toVersion(),
|
||||||
ORG_JOINMASTODON_STATUSES_TRANSLATE to "1.0.0".toVersion(),
|
ORG_JOINMASTODON_STATUSES_TRANSLATE to "1.0.0".toVersion(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -205,6 +208,7 @@ class ServerTest(
|
||||||
ORG_JOINMASTODON_SEARCH_QUERY_IS_SENSITIVE to "1.0.0".toVersion(),
|
ORG_JOINMASTODON_SEARCH_QUERY_IS_SENSITIVE to "1.0.0".toVersion(),
|
||||||
ORG_JOINMASTODON_SEARCH_QUERY_IN_LIBRARY to "1.0.0".toVersion(),
|
ORG_JOINMASTODON_SEARCH_QUERY_IN_LIBRARY to "1.0.0".toVersion(),
|
||||||
ORG_JOINMASTODON_SEARCH_QUERY_BY_DATE to "1.0.0".toVersion(),
|
ORG_JOINMASTODON_SEARCH_QUERY_BY_DATE to "1.0.0".toVersion(),
|
||||||
|
ORG_JOINMASTODON_STATUSES_SCHEDULED to "1.0.0".toVersion(),
|
||||||
ORG_JOINMASTODON_STATUSES_TRANSLATE to "1.1.0".toVersion(),
|
ORG_JOINMASTODON_STATUSES_TRANSLATE to "1.1.0".toVersion(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -212,7 +216,7 @@ class ServerTest(
|
||||||
),
|
),
|
||||||
arrayOf(
|
arrayOf(
|
||||||
Triple(
|
Triple(
|
||||||
"GoToSocial has no translation or filtering",
|
"GoToSocial has no translation, filtering, or scheduling",
|
||||||
NodeInfo.Software("gotosocial", "0.13.1 git-ccecf5a"),
|
NodeInfo.Software("gotosocial", "0.13.1 git-ccecf5a"),
|
||||||
defaultInstance,
|
defaultInstance,
|
||||||
),
|
),
|
||||||
|
@ -260,7 +264,7 @@ class ServerTest(
|
||||||
),
|
),
|
||||||
arrayOf(
|
arrayOf(
|
||||||
Triple(
|
Triple(
|
||||||
"Pleroma can filter",
|
"Pleroma can filter, schedule",
|
||||||
NodeInfo.Software("pleroma", "2.6.50-875-g2eb5c453.service-origin+soapbox"),
|
NodeInfo.Software("pleroma", "2.6.50-875-g2eb5c453.service-origin+soapbox"),
|
||||||
defaultInstance,
|
defaultInstance,
|
||||||
),
|
),
|
||||||
|
@ -270,13 +274,14 @@ class ServerTest(
|
||||||
version = "2.6.50-875-g2eb5c453.service-origin+soapbox".toVersion(),
|
version = "2.6.50-875-g2eb5c453.service-origin+soapbox".toVersion(),
|
||||||
capabilities = mapOf(
|
capabilities = mapOf(
|
||||||
ORG_JOINMASTODON_FILTERS_SERVER to "1.0.0".toVersion(),
|
ORG_JOINMASTODON_FILTERS_SERVER to "1.0.0".toVersion(),
|
||||||
|
ORG_JOINMASTODON_STATUSES_SCHEDULED to "1.0.0".toVersion(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
arrayOf(
|
arrayOf(
|
||||||
Triple(
|
Triple(
|
||||||
"Akkoma can filter",
|
"Akkoma can filter, schedule",
|
||||||
NodeInfo.Software("akkoma", "3.9.3-0-gd83f5f66f-blob"),
|
NodeInfo.Software("akkoma", "3.9.3-0-gd83f5f66f-blob"),
|
||||||
defaultInstance,
|
defaultInstance,
|
||||||
),
|
),
|
||||||
|
@ -286,6 +291,7 @@ class ServerTest(
|
||||||
version = "3.9.3-0-gd83f5f66f-blob".toVersion(),
|
version = "3.9.3-0-gd83f5f66f-blob".toVersion(),
|
||||||
capabilities = mapOf(
|
capabilities = mapOf(
|
||||||
ORG_JOINMASTODON_FILTERS_SERVER to "1.0.0".toVersion(),
|
ORG_JOINMASTODON_FILTERS_SERVER to "1.0.0".toVersion(),
|
||||||
|
ORG_JOINMASTODON_STATUSES_SCHEDULED to "1.0.0".toVersion(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -306,7 +312,7 @@ class ServerTest(
|
||||||
),
|
),
|
||||||
arrayOf(
|
arrayOf(
|
||||||
Triple(
|
Triple(
|
||||||
"Friendica can filter",
|
"Friendica can filter, schedule",
|
||||||
NodeInfo.Software("friendica", "2023.05-1542"),
|
NodeInfo.Software("friendica", "2023.05-1542"),
|
||||||
defaultInstance,
|
defaultInstance,
|
||||||
),
|
),
|
||||||
|
@ -316,6 +322,7 @@ class ServerTest(
|
||||||
version = "2023.5.0".toVersion(),
|
version = "2023.5.0".toVersion(),
|
||||||
capabilities = mapOf(
|
capabilities = mapOf(
|
||||||
ORG_JOINMASTODON_FILTERS_SERVER to "1.0.0".toVersion(),
|
ORG_JOINMASTODON_FILTERS_SERVER to "1.0.0".toVersion(),
|
||||||
|
ORG_JOINMASTODON_STATUSES_SCHEDULED to "1.0.0".toVersion(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
Loading…
Reference in New Issue