Merge pull request #7258 from vector-im/feature/fre/voice_broadcast_feature_flag

Voice Broadcast - Add a feature flag with the composer action
This commit is contained in:
Florian Renaud 2022-10-04 11:25:33 +02:00 committed by GitHub
commit 8e3b9735c1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 63 additions and 1 deletions

1
changelog.d/7258.wip Normal file
View File

@ -0,0 +1 @@
[Voice Broadcast] Add a feature flag with the composer action

View File

@ -1872,6 +1872,7 @@
<string name="attachment_type_sticker">"Sticker"</string>
<string name="attachment_type_poll">Poll</string>
<string name="attachment_type_location">Location</string>
<string name="attachment_type_voice_broadcast">Voice Broadcast</string>
<string name="rotate_and_crop_screen_title">Rotate and crop</string>
<string name="error_handling_incoming_share">Couldn\'t handle share data</string>
@ -3177,6 +3178,7 @@
<string name="tooltip_attachment_contact">Open contacts</string>
<string name="tooltip_attachment_poll">Create poll</string>
<string name="tooltip_attachment_location">Share location</string>
<string name="tooltip_attachment_voice_broadcast">Start a voice broadcast</string>
<string name="message_reaction_show_less">Show less</string>
<plurals name="message_reaction_show_more">

View File

@ -90,6 +90,11 @@ class DebugFeaturesStateFactory @Inject constructor(
key = DebugFeatureKeys.newDeviceManagementEnabled,
factory = VectorFeatures::isNewDeviceManagementEnabled
),
createBooleanFeature(
label = "Enable Voice Broadcast",
key = DebugFeatureKeys.voiceBroadcastEnabled,
factory = VectorFeatures::isVoiceBroadcastEnabled
),
)
)
}

View File

@ -79,6 +79,9 @@ class DebugVectorFeatures(
override fun isNewDeviceManagementEnabled(): Boolean = read(DebugFeatureKeys.newDeviceManagementEnabled)
?: vectorFeatures.isNewDeviceManagementEnabled()
override fun isVoiceBroadcastEnabled(): Boolean = read(DebugFeatureKeys.voiceBroadcastEnabled)
?: vectorFeatures.isVoiceBroadcastEnabled()
fun <T> override(value: T?, key: Preferences.Key<T>) = updatePreferences {
if (value == null) {
it.remove(key)
@ -140,4 +143,5 @@ object DebugFeatureKeys {
val startDmOnFirstMsg = booleanPreferencesKey("start-dm-on-first-msg")
val newAppLayoutEnabled = booleanPreferencesKey("new-app-layout-enabled")
val newDeviceManagementEnabled = booleanPreferencesKey("new-device-management-enabled")
val voiceBroadcastEnabled = booleanPreferencesKey("voice-broadcast-enabled")
}

View File

@ -42,6 +42,7 @@ val PERMISSIONS_FOR_ROOM_AVATAR = listOf(Manifest.permission.CAMERA)
val PERMISSIONS_FOR_WRITING_FILES = listOf(Manifest.permission.WRITE_EXTERNAL_STORAGE)
val PERMISSIONS_FOR_PICKING_CONTACT = listOf(Manifest.permission.READ_CONTACTS)
val PERMISSIONS_FOR_FOREGROUND_LOCATION_SHARING = listOf(Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION)
val PERMISSIONS_FOR_VOICE_BROADCAST = listOf(Manifest.permission.RECORD_AUDIO)
// This is not ideal to store the value like that, but it works
private var permissionDialogDisplayed = false

View File

@ -41,6 +41,7 @@ interface VectorFeatures {
*/
fun isNewAppLayoutFeatureEnabled(): Boolean
fun isNewDeviceManagementEnabled(): Boolean
fun isVoiceBroadcastEnabled(): Boolean
}
class DefaultVectorFeatures : VectorFeatures {
@ -57,4 +58,5 @@ class DefaultVectorFeatures : VectorFeatures {
override fun forceUsageOfOpusEncoder(): Boolean = false
override fun isNewAppLayoutFeatureEnabled(): Boolean = true
override fun isNewDeviceManagementEnabled(): Boolean = false
override fun isVoiceBroadcastEnabled(): Boolean = false
}

View File

@ -40,6 +40,7 @@ import im.vector.app.core.utils.PERMISSIONS_EMPTY
import im.vector.app.core.utils.PERMISSIONS_FOR_FOREGROUND_LOCATION_SHARING
import im.vector.app.core.utils.PERMISSIONS_FOR_PICKING_CONTACT
import im.vector.app.core.utils.PERMISSIONS_FOR_TAKING_PHOTO
import im.vector.app.core.utils.PERMISSIONS_FOR_VOICE_BROADCAST
import im.vector.app.databinding.ViewAttachmentTypeSelectorBinding
import im.vector.app.features.attachments.AttachmentTypeSelectorView.Callback
import kotlin.math.max
@ -75,6 +76,7 @@ class AttachmentTypeSelectorView(
views.attachmentContactButton.configure(Type.CONTACT)
views.attachmentPollButton.configure(Type.POLL)
views.attachmentLocationButton.configure(Type.LOCATION)
views.attachmentVoiceBroadcast.configure(Type.VOICE_BROADCAST)
width = LinearLayout.LayoutParams.MATCH_PARENT
height = LinearLayout.LayoutParams.WRAP_CONTENT
animationStyle = 0
@ -134,6 +136,7 @@ class AttachmentTypeSelectorView(
Type.CONTACT -> views.attachmentContactButton
Type.POLL -> views.attachmentPollButton
Type.LOCATION -> views.attachmentLocationButton
Type.VOICE_BROADCAST -> views.attachmentVoiceBroadcast
}.let {
it.isVisible = isVisible
}
@ -221,6 +224,7 @@ class AttachmentTypeSelectorView(
STICKER(PERMISSIONS_EMPTY, R.string.tooltip_attachment_sticker),
CONTACT(PERMISSIONS_FOR_PICKING_CONTACT, R.string.tooltip_attachment_contact),
POLL(PERMISSIONS_EMPTY, R.string.tooltip_attachment_poll),
LOCATION(PERMISSIONS_FOR_FOREGROUND_LOCATION_SHARING, R.string.tooltip_attachment_location)
LOCATION(PERMISSIONS_FOR_FOREGROUND_LOCATION_SHARING, R.string.tooltip_attachment_location),
VOICE_BROADCAST(PERMISSIONS_FOR_VOICE_BROADCAST, R.string.tooltip_attachment_voice_broadcast),
}
}

View File

@ -79,6 +79,7 @@ sealed class RoomDetailAction : VectorViewModelAction {
data class ReRequestKeys(val eventId: String) : RoomDetailAction()
object SelectStickerAttachment : RoomDetailAction()
object StartVoiceBroadcast : RoomDetailAction()
object OpenIntegrationManager : RoomDetailAction()
object ManageIntegrations : RoomDetailAction()
data class AddJitsiWidget(val withVideo: Boolean) : RoomDetailAction()

View File

@ -1575,6 +1575,10 @@ class TimelineFragment :
attachmentTypeSelector.setAttachmentVisibility(
AttachmentTypeSelectorView.Type.POLL, !isThreadTimeLine()
)
attachmentTypeSelector.setAttachmentVisibility(
AttachmentTypeSelectorView.Type.VOICE_BROADCAST,
vectorFeatures.isVoiceBroadcastEnabled(), // TODO check user permission
)
}
attachmentTypeSelector.show(views.composerLayout.views.attachmentButton)
}
@ -2668,6 +2672,7 @@ class TimelineFragment :
locationOwnerId = session.myUserId
)
}
AttachmentTypeSelectorView.Type.VOICE_BROADCAST -> timelineViewModel.handle(RoomDetailAction.StartVoiceBroadcast)
}
}

View File

@ -456,6 +456,7 @@ class TimelineViewModel @AssistedInject constructor(
is RoomDetailAction.ReRequestKeys -> handleReRequestKeys(action)
is RoomDetailAction.TapOnFailedToDecrypt -> handleTapOnFailedToDecrypt(action)
is RoomDetailAction.SelectStickerAttachment -> handleSelectStickerAttachment()
is RoomDetailAction.StartVoiceBroadcast -> handleStartVoiceBroadcast()
is RoomDetailAction.OpenIntegrationManager -> handleOpenIntegrationManager()
is RoomDetailAction.StartCall -> handleStartCall(action)
is RoomDetailAction.AcceptCall -> handleAcceptCall(action)
@ -597,6 +598,11 @@ class TimelineViewModel @AssistedInject constructor(
}
}
private fun handleStartVoiceBroadcast() {
// Todo implement start voice broadcast action
Timber.d("Start voice broadcast clicked")
}
private fun handleOpenIntegrationManager() {
viewModelScope.launch {
val viewEvent = withContext(Dispatchers.Default) {

View File

@ -0,0 +1,21 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M20.189,4.187C19.85,3.751 19.222,3.672 18.785,4.011C18.35,4.35 18.271,4.977 18.609,5.413L18.61,5.414L18.611,5.415L18.624,5.434C18.638,5.451 18.659,5.48 18.687,5.52C18.744,5.6 18.828,5.722 18.931,5.884C19.137,6.207 19.415,6.683 19.693,7.281C20.253,8.481 20.799,10.134 20.799,12.001C20.799,13.867 20.253,15.52 19.693,16.721C19.415,17.318 19.137,17.794 18.931,18.117C18.828,18.279 18.744,18.401 18.687,18.481C18.659,18.521 18.638,18.55 18.624,18.568L18.611,18.586L18.61,18.587L18.609,18.588C18.271,19.024 18.35,19.651 18.785,19.99C19.222,20.329 19.85,20.25 20.189,19.815L19.444,19.235C20.189,19.815 20.189,19.815 20.189,19.815L20.191,19.812L20.194,19.808L20.202,19.797L20.229,19.762C20.25,19.733 20.281,19.691 20.318,19.639C20.393,19.534 20.496,19.383 20.618,19.191C20.862,18.807 21.184,18.255 21.506,17.566C22.145,16.195 22.799,14.248 22.799,12.001C22.799,9.753 22.145,7.806 21.506,6.435C21.184,5.746 20.862,5.194 20.618,4.81C20.496,4.618 20.393,4.467 20.318,4.362C20.281,4.31 20.25,4.268 20.229,4.239L20.202,4.204L20.194,4.193L20.191,4.189L20.19,4.188C20.19,4.188 20.189,4.187 19.399,4.801L20.189,4.187Z"
android:fillColor="#737D8C" />
<path
android:pathData="M17.59,7.787C17.251,7.351 16.622,7.272 16.186,7.611C15.752,7.95 15.672,8.576 16.008,9.011L16.012,9.016C16.016,9.022 16.025,9.033 16.037,9.05C16.06,9.084 16.098,9.138 16.144,9.211C16.237,9.357 16.365,9.576 16.494,9.852C16.754,10.41 17,11.163 17,12.001C17,12.839 16.754,13.592 16.494,14.149C16.365,14.425 16.237,14.644 16.144,14.791C16.098,14.864 16.06,14.918 16.037,14.951C16.025,14.968 16.016,14.98 16.012,14.986L16.008,14.99C15.672,15.426 15.752,16.052 16.186,16.39C16.622,16.729 17.251,16.651 17.59,16.215L16.8,15.601C17.59,16.215 17.59,16.215 17.59,16.215L17.591,16.212L17.594,16.21L17.599,16.202L17.616,16.18C17.629,16.163 17.646,16.139 17.667,16.11C17.709,16.051 17.765,15.968 17.831,15.865C17.963,15.657 18.135,15.362 18.306,14.995C18.646,14.267 19,13.22 19,12.001C19,10.782 18.646,9.735 18.306,9.006C18.135,8.639 17.963,8.344 17.831,8.137C17.765,8.033 17.709,7.951 17.667,7.892C17.646,7.863 17.629,7.839 17.616,7.821L17.599,7.799L17.594,7.792L17.591,7.789L17.59,7.788C17.59,7.788 17.59,7.787 16.8,8.401L17.59,7.787Z"
android:fillColor="#737D8C" />
<path
android:pathData="M3.611,19.815C3.95,20.25 4.578,20.329 5.014,19.99C5.45,19.651 5.528,19.024 5.191,18.588L5.19,18.587L5.189,18.586L5.175,18.568C5.162,18.55 5.141,18.521 5.112,18.481C5.056,18.401 4.971,18.279 4.869,18.117C4.663,17.794 4.385,17.318 4.106,16.721C3.546,15.52 3,13.867 3,12C3,10.134 3.546,8.481 4.106,7.281C4.385,6.683 4.663,6.207 4.869,5.884C4.971,5.722 5.056,5.6 5.112,5.52C5.141,5.48 5.162,5.451 5.175,5.433L5.189,5.415L5.19,5.414L5.191,5.413C5.528,4.977 5.449,4.35 5.014,4.011C4.578,3.672 3.95,3.751 3.611,4.187L4.356,4.766C3.611,4.187 3.611,4.187 3.611,4.187L3.609,4.189L3.606,4.193L3.598,4.204L3.571,4.239C3.549,4.268 3.519,4.31 3.482,4.362C3.407,4.467 3.304,4.618 3.181,4.81C2.937,5.194 2.615,5.746 2.294,6.435C1.654,7.806 1,9.753 1,12C1,14.248 1.654,16.195 2.294,17.566C2.615,18.255 2.937,18.807 3.181,19.191C3.304,19.383 3.407,19.534 3.482,19.639C3.519,19.691 3.549,19.733 3.571,19.762L3.598,19.797L3.606,19.808L3.609,19.812L3.61,19.813C3.61,19.813 3.611,19.815 4.4,19.201L3.611,19.815Z"
android:fillColor="#737D8C" />
<path
android:pathData="M6.21,16.214C6.549,16.65 7.177,16.729 7.613,16.39C8.048,16.052 8.127,15.426 7.791,14.99L7.788,14.985C7.783,14.979 7.775,14.968 7.763,14.951C7.739,14.917 7.702,14.863 7.655,14.79C7.562,14.644 7.434,14.425 7.305,14.149C7.045,13.591 6.799,12.838 6.799,12C6.799,11.162 7.045,10.409 7.305,9.852C7.434,9.576 7.562,9.357 7.655,9.21C7.702,9.137 7.739,9.083 7.763,9.05C7.775,9.033 7.783,9.021 7.788,9.015L7.791,9.011C8.127,8.575 8.048,7.949 7.613,7.611C7.177,7.272 6.549,7.35 6.21,7.786L6.999,8.4C6.21,7.786 6.21,7.786 6.21,7.786L6.208,7.789L6.206,7.792L6.2,7.799L6.184,7.821C6.171,7.838 6.153,7.862 6.132,7.892C6.091,7.951 6.034,8.033 5.968,8.137C5.836,8.344 5.664,8.639 5.493,9.006C5.153,9.734 4.799,10.781 4.799,12C4.799,13.219 5.153,14.267 5.493,14.995C5.664,15.362 5.836,15.657 5.968,15.864C6.034,15.968 6.091,16.05 6.132,16.109C6.153,16.139 6.171,16.162 6.184,16.18L6.2,16.202L6.206,16.209L6.208,16.212L6.209,16.213C6.209,16.213 6.21,16.214 6.999,15.6L6.21,16.214Z"
android:fillColor="#737D8C" />
<path
android:pathData="M12,12m-2,0a2,2 0,1 1,4 0a2,2 0,1 1,-4 0"
android:fillColor="#737D8C" />
</vector>

View File

@ -63,6 +63,16 @@
android:src="@drawable/ic_attachment_file"
app:tint="?colorPrimary" />
<ImageButton
android:id="@+id/attachmentVoiceBroadcast"
android:layout_width="@dimen/layout_touch_size"
android:layout_height="@dimen/layout_touch_size"
android:layout_marginStart="2dp"
android:background="?android:attr/selectableItemBackground"
android:contentDescription="@string/attachment_type_voice_broadcast"
android:src="@drawable/ic_attachment_voice_broadcast"
app:tint="?colorPrimary" />
<ImageButton
android:id="@+id/attachmentPollButton"
android:layout_width="@dimen/layout_touch_size"