Merge pull request #2202 from vector-im/feature/bma/shortcuts
Feature/bma/shortcuts
This commit is contained in:
commit
61a41493ac
|
@ -9,6 +9,7 @@ Improvements 🙌:
|
||||||
- PIN code: request PIN code if phone has been locked
|
- PIN code: request PIN code if phone has been locked
|
||||||
- Small optimisation of scrolling experience in timeline (#2114)
|
- Small optimisation of scrolling experience in timeline (#2114)
|
||||||
- Allow user to reset cross signing if he has no way to recover (#2052)
|
- Allow user to reset cross signing if he has no way to recover (#2052)
|
||||||
|
- Create home shortcut for any room (#1525)
|
||||||
|
|
||||||
Bugfix 🐛:
|
Bugfix 🐛:
|
||||||
- Improve support for image/audio/video/file selection with intent changes (#1376)
|
- Improve support for image/audio/video/file selection with intent changes (#1376)
|
||||||
|
|
|
@ -0,0 +1,78 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020 New Vector Ltd
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package im.vector.app.features.home
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.graphics.Bitmap
|
||||||
|
import android.os.Build
|
||||||
|
import androidx.annotation.WorkerThread
|
||||||
|
import androidx.core.content.pm.ShortcutInfoCompat
|
||||||
|
import androidx.core.content.pm.ShortcutManagerCompat
|
||||||
|
import androidx.core.graphics.drawable.IconCompat
|
||||||
|
import im.vector.app.core.glide.GlideApp
|
||||||
|
import im.vector.app.core.utils.DimensionConverter
|
||||||
|
import im.vector.app.features.home.room.detail.RoomDetailActivity
|
||||||
|
import org.matrix.android.sdk.api.session.room.model.RoomSummary
|
||||||
|
import org.matrix.android.sdk.api.util.toMatrixItem
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
private val useAdaptiveIcon = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O
|
||||||
|
private const val adaptiveIconSizeDp = 108
|
||||||
|
private const val adaptiveIconOuterSidesDp = 18
|
||||||
|
|
||||||
|
class ShortcutCreator @Inject constructor(
|
||||||
|
private val context: Context,
|
||||||
|
private val avatarRenderer: AvatarRenderer,
|
||||||
|
private val dimensionConverter: DimensionConverter
|
||||||
|
) {
|
||||||
|
private val adaptiveIconSize = dimensionConverter.dpToPx(adaptiveIconSizeDp)
|
||||||
|
private val adaptiveIconOuterSides = dimensionConverter.dpToPx(adaptiveIconOuterSidesDp)
|
||||||
|
private val iconSize by lazy {
|
||||||
|
if (useAdaptiveIcon) {
|
||||||
|
adaptiveIconSize - adaptiveIconOuterSides
|
||||||
|
} else {
|
||||||
|
dimensionConverter.dpToPx(72)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun canCreateShortcut(): Boolean {
|
||||||
|
return ShortcutManagerCompat.isRequestPinShortcutSupported(context)
|
||||||
|
}
|
||||||
|
|
||||||
|
@WorkerThread
|
||||||
|
fun create(roomSummary: RoomSummary): ShortcutInfoCompat {
|
||||||
|
val intent = RoomDetailActivity.shortcutIntent(context, roomSummary.roomId)
|
||||||
|
val bitmap = try {
|
||||||
|
avatarRenderer.shortcutDrawable(GlideApp.with(context), roomSummary.toMatrixItem(), iconSize)
|
||||||
|
} catch (failure: Throwable) {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
return ShortcutInfoCompat.Builder(context, roomSummary.roomId)
|
||||||
|
.setShortLabel(roomSummary.displayName)
|
||||||
|
.setIcon(bitmap?.toProfileImageIcon())
|
||||||
|
.setIntent(intent)
|
||||||
|
.build()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun Bitmap.toProfileImageIcon(): IconCompat {
|
||||||
|
return if (useAdaptiveIcon) {
|
||||||
|
IconCompat.createWithAdaptiveBitmap(this)
|
||||||
|
} else {
|
||||||
|
IconCompat.createWithBitmap(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,40 +18,19 @@ package im.vector.app.features.home
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.pm.ShortcutManager
|
import android.content.pm.ShortcutManager
|
||||||
import android.graphics.Bitmap
|
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import androidx.core.content.getSystemService
|
import androidx.core.content.getSystemService
|
||||||
import androidx.core.content.pm.ShortcutInfoCompat
|
|
||||||
import androidx.core.content.pm.ShortcutManagerCompat
|
import androidx.core.content.pm.ShortcutManagerCompat
|
||||||
import androidx.core.graphics.drawable.IconCompat
|
|
||||||
import im.vector.app.core.glide.GlideApp
|
|
||||||
import im.vector.app.core.utils.DimensionConverter
|
|
||||||
import im.vector.app.features.home.room.detail.RoomDetailActivity
|
|
||||||
import org.matrix.android.sdk.api.util.toMatrixItem
|
|
||||||
import io.reactivex.Observable
|
import io.reactivex.Observable
|
||||||
import io.reactivex.disposables.Disposable
|
import io.reactivex.disposables.Disposable
|
||||||
import io.reactivex.schedulers.Schedulers
|
import io.reactivex.schedulers.Schedulers
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
private val useAdaptiveIcon = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O
|
|
||||||
private const val adaptiveIconSizeDp = 108
|
|
||||||
private const val adaptiveIconOuterSidesDp = 18
|
|
||||||
|
|
||||||
class ShortcutsHandler @Inject constructor(
|
class ShortcutsHandler @Inject constructor(
|
||||||
private val context: Context,
|
private val context: Context,
|
||||||
private val homeRoomListStore: HomeRoomListDataSource,
|
private val homeRoomListStore: HomeRoomListDataSource,
|
||||||
private val avatarRenderer: AvatarRenderer,
|
private val shortcutCreator: ShortcutCreator
|
||||||
private val dimensionConverter: DimensionConverter
|
|
||||||
) {
|
) {
|
||||||
private val adaptiveIconSize = dimensionConverter.dpToPx(adaptiveIconSizeDp)
|
|
||||||
private val adaptiveIconOuterSides = dimensionConverter.dpToPx(adaptiveIconOuterSidesDp)
|
|
||||||
private val iconSize by lazy {
|
|
||||||
if (useAdaptiveIcon) {
|
|
||||||
adaptiveIconSize - adaptiveIconOuterSides
|
|
||||||
} else {
|
|
||||||
dimensionConverter.dpToPx(72)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun observeRoomsAndBuildShortcuts(): Disposable {
|
fun observeRoomsAndBuildShortcuts(): Disposable {
|
||||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N_MR1) {
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N_MR1) {
|
||||||
|
@ -67,19 +46,7 @@ class ShortcutsHandler @Inject constructor(
|
||||||
val shortcuts = rooms
|
val shortcuts = rooms
|
||||||
.filter { room -> room.isFavorite }
|
.filter { room -> room.isFavorite }
|
||||||
.take(n = 4) // Android only allows us to create 4 shortcuts
|
.take(n = 4) // Android only allows us to create 4 shortcuts
|
||||||
.map { room ->
|
.map { shortcutCreator.create(it) }
|
||||||
val intent = RoomDetailActivity.shortcutIntent(context, room.roomId)
|
|
||||||
val bitmap = try {
|
|
||||||
avatarRenderer.shortcutDrawable(GlideApp.with(context), room.toMatrixItem(), iconSize)
|
|
||||||
} catch (failure: Throwable) {
|
|
||||||
null
|
|
||||||
}
|
|
||||||
ShortcutInfoCompat.Builder(context, room.roomId)
|
|
||||||
.setShortLabel(room.displayName)
|
|
||||||
.setIcon(bitmap?.toProfileImageIcon())
|
|
||||||
.setIntent(intent)
|
|
||||||
.build()
|
|
||||||
}
|
|
||||||
|
|
||||||
ShortcutManagerCompat.removeAllDynamicShortcuts(context)
|
ShortcutManagerCompat.removeAllDynamicShortcuts(context)
|
||||||
ShortcutManagerCompat.addDynamicShortcuts(context, shortcuts)
|
ShortcutManagerCompat.addDynamicShortcuts(context, shortcuts)
|
||||||
|
@ -104,14 +71,4 @@ class ShortcutsHandler @Inject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// PRIVATE API *********************************************************************************
|
|
||||||
|
|
||||||
private fun Bitmap.toProfileImageIcon(): IconCompat {
|
|
||||||
return if (useAdaptiveIcon) {
|
|
||||||
IconCompat.createWithAdaptiveBitmap(this)
|
|
||||||
} else {
|
|
||||||
IconCompat.createWithBitmap(this)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,4 +26,5 @@ sealed class RoomProfileAction: VectorViewModelAction {
|
||||||
data class ChangeRoomNotificationState(val notificationState: RoomNotificationState) : RoomProfileAction()
|
data class ChangeRoomNotificationState(val notificationState: RoomNotificationState) : RoomProfileAction()
|
||||||
data class ChangeRoomAvatar(val uri: Uri, val fileName: String?) : RoomProfileAction()
|
data class ChangeRoomAvatar(val uri: Uri, val fileName: String?) : RoomProfileAction()
|
||||||
object ShareRoomProfile : RoomProfileAction()
|
object ShareRoomProfile : RoomProfileAction()
|
||||||
|
object CreateShortcut : RoomProfileAction()
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@ import im.vector.app.core.epoxy.profiles.buildProfileSection
|
||||||
import im.vector.app.core.resources.ColorProvider
|
import im.vector.app.core.resources.ColorProvider
|
||||||
import im.vector.app.core.resources.StringProvider
|
import im.vector.app.core.resources.StringProvider
|
||||||
import im.vector.app.core.ui.list.genericFooterItem
|
import im.vector.app.core.ui.list.genericFooterItem
|
||||||
|
import im.vector.app.features.home.ShortcutCreator
|
||||||
import im.vector.app.features.settings.VectorPreferences
|
import im.vector.app.features.settings.VectorPreferences
|
||||||
import org.matrix.android.sdk.api.crypto.RoomEncryptionTrustLevel
|
import org.matrix.android.sdk.api.crypto.RoomEncryptionTrustLevel
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
@ -31,6 +32,7 @@ import javax.inject.Inject
|
||||||
class RoomProfileController @Inject constructor(
|
class RoomProfileController @Inject constructor(
|
||||||
private val stringProvider: StringProvider,
|
private val stringProvider: StringProvider,
|
||||||
private val vectorPreferences: VectorPreferences,
|
private val vectorPreferences: VectorPreferences,
|
||||||
|
private val shortcutCreator: ShortcutCreator,
|
||||||
colorProvider: ColorProvider
|
colorProvider: ColorProvider
|
||||||
) : TypedEpoxyController<RoomProfileViewState>() {
|
) : TypedEpoxyController<RoomProfileViewState>() {
|
||||||
|
|
||||||
|
@ -44,6 +46,7 @@ class RoomProfileController @Inject constructor(
|
||||||
fun onBannedMemberListClicked()
|
fun onBannedMemberListClicked()
|
||||||
fun onNotificationsClicked()
|
fun onNotificationsClicked()
|
||||||
fun onUploadsClicked()
|
fun onUploadsClicked()
|
||||||
|
fun createShortcut()
|
||||||
fun onSettingsClicked()
|
fun onSettingsClicked()
|
||||||
fun onLeaveRoomClicked()
|
fun onLeaveRoomClicked()
|
||||||
fun onRoomIdClicked()
|
fun onRoomIdClicked()
|
||||||
|
@ -114,6 +117,16 @@ class RoomProfileController @Inject constructor(
|
||||||
icon = R.drawable.ic_room_profile_uploads,
|
icon = R.drawable.ic_room_profile_uploads,
|
||||||
action = { callback?.onUploadsClicked() }
|
action = { callback?.onUploadsClicked() }
|
||||||
)
|
)
|
||||||
|
if (shortcutCreator.canCreateShortcut()) {
|
||||||
|
buildProfileAction(
|
||||||
|
id = "shortcut",
|
||||||
|
title = stringProvider.getString(R.string.room_settings_add_homescreen_shortcut),
|
||||||
|
dividerColor = dividerColor,
|
||||||
|
editable = false,
|
||||||
|
icon = R.drawable.ic_add_to_home_screen_24dp,
|
||||||
|
action = { callback?.createShortcut() }
|
||||||
|
)
|
||||||
|
}
|
||||||
buildProfileAction(
|
buildProfileAction(
|
||||||
id = "leave",
|
id = "leave",
|
||||||
title = stringProvider.getString(if (roomSummary.isDirect) {
|
title = stringProvider.getString(if (roomSummary.isDirect) {
|
||||||
|
@ -124,6 +137,7 @@ class RoomProfileController @Inject constructor(
|
||||||
dividerColor = dividerColor,
|
dividerColor = dividerColor,
|
||||||
divider = false,
|
divider = false,
|
||||||
destructive = true,
|
destructive = true,
|
||||||
|
icon = R.drawable.ic_room_actions_leave,
|
||||||
editable = false,
|
editable = false,
|
||||||
action = { callback?.onLeaveRoomClicked() }
|
action = { callback?.onLeaveRoomClicked() }
|
||||||
)
|
)
|
||||||
|
|
|
@ -27,6 +27,7 @@ import android.view.View
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.appcompat.app.AlertDialog
|
import androidx.appcompat.app.AlertDialog
|
||||||
import androidx.core.app.ActivityOptionsCompat
|
import androidx.core.app.ActivityOptionsCompat
|
||||||
|
import androidx.core.content.pm.ShortcutManagerCompat
|
||||||
import androidx.core.net.toUri
|
import androidx.core.net.toUri
|
||||||
import androidx.core.view.ViewCompat
|
import androidx.core.view.ViewCompat
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
|
@ -115,6 +116,7 @@ class RoomProfileFragment @Inject constructor(
|
||||||
is RoomProfileViewEvents.Failure -> showFailure(it.throwable)
|
is RoomProfileViewEvents.Failure -> showFailure(it.throwable)
|
||||||
is RoomProfileViewEvents.ShareRoomProfile -> onShareRoomProfile(it.permalink)
|
is RoomProfileViewEvents.ShareRoomProfile -> onShareRoomProfile(it.permalink)
|
||||||
RoomProfileViewEvents.OnChangeAvatarSuccess -> dismissLoadingDialog()
|
RoomProfileViewEvents.OnChangeAvatarSuccess -> dismissLoadingDialog()
|
||||||
|
is RoomProfileViewEvents.OnShortcutReady -> addShortcut(it)
|
||||||
}.exhaustive
|
}.exhaustive
|
||||||
}
|
}
|
||||||
roomListQuickActionsSharedActionViewModel
|
roomListQuickActionsSharedActionViewModel
|
||||||
|
@ -232,6 +234,16 @@ class RoomProfileFragment @Inject constructor(
|
||||||
roomProfileSharedActionViewModel.post(RoomProfileSharedAction.OpenRoomUploads)
|
roomProfileSharedActionViewModel.post(RoomProfileSharedAction.OpenRoomUploads)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun createShortcut() {
|
||||||
|
// Ask the view model to prepare it...
|
||||||
|
roomProfileViewModel.handle(RoomProfileAction.CreateShortcut)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun addShortcut(onShortcutReady: RoomProfileViewEvents.OnShortcutReady) {
|
||||||
|
// ... and propose the user to add it
|
||||||
|
ShortcutManagerCompat.requestPinShortcut(requireContext(), onShortcutReady.shortcutInfo, null)
|
||||||
|
}
|
||||||
|
|
||||||
override fun onLeaveRoomClicked() {
|
override fun onLeaveRoomClicked() {
|
||||||
AlertDialog.Builder(requireContext())
|
AlertDialog.Builder(requireContext())
|
||||||
.setTitle(R.string.room_participants_leave_prompt_title)
|
.setTitle(R.string.room_participants_leave_prompt_title)
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
package im.vector.app.features.roomprofile
|
package im.vector.app.features.roomprofile
|
||||||
|
|
||||||
|
import androidx.core.content.pm.ShortcutInfoCompat
|
||||||
import im.vector.app.core.platform.VectorViewEvents
|
import im.vector.app.core.platform.VectorViewEvents
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -27,4 +28,5 @@ sealed class RoomProfileViewEvents : VectorViewEvents {
|
||||||
|
|
||||||
object OnChangeAvatarSuccess : RoomProfileViewEvents()
|
object OnChangeAvatarSuccess : RoomProfileViewEvents()
|
||||||
data class ShareRoomProfile(val permalink: String) : RoomProfileViewEvents()
|
data class ShareRoomProfile(val permalink: String) : RoomProfileViewEvents()
|
||||||
|
data class OnShortcutReady(val shortcutInfo: ShortcutInfoCompat) : RoomProfileViewEvents()
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,15 +17,20 @@
|
||||||
|
|
||||||
package im.vector.app.features.roomprofile
|
package im.vector.app.features.roomprofile
|
||||||
|
|
||||||
|
import androidx.lifecycle.viewModelScope
|
||||||
import com.airbnb.mvrx.FragmentViewModelContext
|
import com.airbnb.mvrx.FragmentViewModelContext
|
||||||
import com.airbnb.mvrx.MvRxViewModelFactory
|
import com.airbnb.mvrx.MvRxViewModelFactory
|
||||||
import com.airbnb.mvrx.ViewModelContext
|
import com.airbnb.mvrx.ViewModelContext
|
||||||
import com.squareup.inject.assisted.Assisted
|
import com.squareup.inject.assisted.Assisted
|
||||||
import com.squareup.inject.assisted.AssistedInject
|
import com.squareup.inject.assisted.AssistedInject
|
||||||
import im.vector.app.R
|
import im.vector.app.R
|
||||||
|
import im.vector.app.core.extensions.exhaustive
|
||||||
import im.vector.app.core.platform.VectorViewModel
|
import im.vector.app.core.platform.VectorViewModel
|
||||||
import im.vector.app.core.resources.StringProvider
|
import im.vector.app.core.resources.StringProvider
|
||||||
|
import im.vector.app.features.home.ShortcutCreator
|
||||||
import im.vector.app.features.powerlevel.PowerLevelsObservableFactory
|
import im.vector.app.features.powerlevel.PowerLevelsObservableFactory
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
import org.matrix.android.sdk.api.MatrixCallback
|
import org.matrix.android.sdk.api.MatrixCallback
|
||||||
import org.matrix.android.sdk.api.session.Session
|
import org.matrix.android.sdk.api.session.Session
|
||||||
import org.matrix.android.sdk.api.session.events.model.EventType
|
import org.matrix.android.sdk.api.session.events.model.EventType
|
||||||
|
@ -36,10 +41,12 @@ import org.matrix.android.sdk.rx.rx
|
||||||
import org.matrix.android.sdk.rx.unwrap
|
import org.matrix.android.sdk.rx.unwrap
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
|
|
||||||
class RoomProfileViewModel @AssistedInject constructor(@Assisted private val initialState: RoomProfileViewState,
|
class RoomProfileViewModel @AssistedInject constructor(
|
||||||
private val stringProvider: StringProvider,
|
@Assisted private val initialState: RoomProfileViewState,
|
||||||
private val session: Session)
|
private val stringProvider: StringProvider,
|
||||||
: VectorViewModel<RoomProfileViewState, RoomProfileAction, RoomProfileViewEvents>(initialState) {
|
private val shortcutCreator: ShortcutCreator,
|
||||||
|
private val session: Session
|
||||||
|
) : VectorViewModel<RoomProfileViewState, RoomProfileAction, RoomProfileViewEvents>(initialState) {
|
||||||
|
|
||||||
@AssistedInject.Factory
|
@AssistedInject.Factory
|
||||||
interface Factory {
|
interface Factory {
|
||||||
|
@ -88,11 +95,24 @@ class RoomProfileViewModel @AssistedInject constructor(@Assisted private val ini
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun handle(action: RoomProfileAction) = when (action) {
|
override fun handle(action: RoomProfileAction) {
|
||||||
RoomProfileAction.LeaveRoom -> handleLeaveRoom()
|
when (action) {
|
||||||
is RoomProfileAction.ChangeRoomNotificationState -> handleChangeNotificationMode(action)
|
RoomProfileAction.LeaveRoom -> handleLeaveRoom()
|
||||||
is RoomProfileAction.ShareRoomProfile -> handleShareRoomProfile()
|
is RoomProfileAction.ChangeRoomNotificationState -> handleChangeNotificationMode(action)
|
||||||
is RoomProfileAction.ChangeRoomAvatar -> handleChangeAvatar(action)
|
is RoomProfileAction.ShareRoomProfile -> handleShareRoomProfile()
|
||||||
|
is RoomProfileAction.ChangeRoomAvatar -> handleChangeAvatar(action)
|
||||||
|
RoomProfileAction.CreateShortcut -> handleCreateShortcut()
|
||||||
|
}.exhaustive
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun handleCreateShortcut() {
|
||||||
|
viewModelScope.launch(Dispatchers.IO) {
|
||||||
|
withState { state ->
|
||||||
|
state.roomSummary()
|
||||||
|
?.let { shortcutCreator.create(it) }
|
||||||
|
?.let { _viewEvents.post(RoomProfileViewEvents.OnShortcutReady(it)) }
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleChangeNotificationMode(action: RoomProfileAction.ChangeRoomNotificationState) {
|
private fun handleChangeNotificationMode(action: RoomProfileAction.ChangeRoomNotificationState) {
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
<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="M18,1.01L8,1C6.9,1 6,1.9 6,3V6C6,6.55 6.45,7 7,7C7.55,7 8,6.55 8,6V4.5H18V19.5H8V18C8,17.45 7.55,17 7,17C6.45,17 6,17.45 6,18V21C6,22.1 6.9,23 8,23H18C19.1,23 20,22.1 20,21V3C20,1.9 19.1,1.01 18,1.01Z"
|
||||||
|
android:fillColor="#000000"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M11,14.45C11,15 10.55,15.45 10,15.45C9.45,15.45 9,15 9,14.45V11.86L4.11,16.75C3.72,17.14 3.09,17.14 2.7,16.75C2.31,16.36 2.31,15.73 2.7,15.34L7.59,10.45H5C4.45,10.45 4,10 4,9.45C4,8.9 4.45,8.45 5,8.45H10C10.55,8.45 11,8.9 11,9.45V14.45Z"
|
||||||
|
android:fillColor="#000000"/>
|
||||||
|
</vector>
|
|
@ -664,7 +664,7 @@
|
||||||
<string name="room_settings_direct_chat">Direct Chat</string>
|
<string name="room_settings_direct_chat">Direct Chat</string>
|
||||||
<string name="room_settings_leave_conversation">Leave Conversation</string>
|
<string name="room_settings_leave_conversation">Leave Conversation</string>
|
||||||
<string name="room_settings_forget">Forget</string>
|
<string name="room_settings_forget">Forget</string>
|
||||||
<string name="room_settings_add_homescreen_shortcut">Add Homescreen Shortcut</string>
|
<string name="room_settings_add_homescreen_shortcut">Add to Home screen</string>
|
||||||
|
|
||||||
<!-- home sliding menu -->
|
<!-- home sliding menu -->
|
||||||
<string name="room_sliding_menu_messages">Messages</string>
|
<string name="room_sliding_menu_messages">Messages</string>
|
||||||
|
|
Loading…
Reference in New Issue