Unverified Commit 1f56cb65 authored by Hussein El Feky's avatar Hussein El Feky Committed by GitHub

Merge branch 'develop' into language-setter

parents b926e94a 3da3ec81
...@@ -18,7 +18,7 @@ android { ...@@ -18,7 +18,7 @@ android {
applicationId "chat.rocket.android" applicationId "chat.rocket.android"
minSdkVersion versions.minSdk minSdkVersion versions.minSdk
targetSdkVersion versions.targetSdk targetSdkVersion versions.targetSdk
versionCode 2061 versionCode 2062
versionName "3.4.0" versionName "3.4.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
multiDexEnabled true multiDexEnabled true
......
...@@ -15,6 +15,10 @@ class ChatRoomsRepository @Inject constructor(private val dao: ChatRoomDao) { ...@@ -15,6 +15,10 @@ class ChatRoomsRepository @Inject constructor(private val dao: ChatRoomDao) {
Order.GROUPED_ACTIVITY -> dao.getAllGrouped() Order.GROUPED_ACTIVITY -> dao.getAllGrouped()
Order.NAME -> dao.getAllAlphabetically() Order.NAME -> dao.getAllAlphabetically()
Order.GROUPED_NAME -> dao.getAllAlphabeticallyGrouped() Order.GROUPED_NAME -> dao.getAllAlphabeticallyGrouped()
Order.UNREAD_ON_TOP_ACTIVITY -> dao.getAllUnread();
Order.UNREAD_ON_TOP_NAME -> dao.getAllAlphabeticallyUnread();
Order.UNREAD_ON_TOP_GROUPED_ACTIVITY -> dao.getAllGroupedUnread();
Order.UNREAD_ON_TOP_GROUPED_NAME -> dao.getAllAlphabeticallyGroupedUnread();
} }
} }
...@@ -28,8 +32,16 @@ class ChatRoomsRepository @Inject constructor(private val dao: ChatRoomDao) { ...@@ -28,8 +32,16 @@ class ChatRoomsRepository @Inject constructor(private val dao: ChatRoomDao) {
GROUPED_ACTIVITY, GROUPED_ACTIVITY,
NAME, NAME,
GROUPED_NAME, GROUPED_NAME,
UNREAD_ON_TOP_ACTIVITY,
UNREAD_ON_TOP_NAME,
UNREAD_ON_TOP_GROUPED_ACTIVITY,
UNREAD_ON_TOP_GROUPED_NAME
} }
} }
fun ChatRoomsRepository.Order.isGrouped(): Boolean = this == ChatRoomsRepository.Order.GROUPED_ACTIVITY fun ChatRoomsRepository.Order.isGrouped(): Boolean = this == ChatRoomsRepository.Order.GROUPED_ACTIVITY
|| this == ChatRoomsRepository.Order.GROUPED_NAME || this == ChatRoomsRepository.Order.GROUPED_NAME
\ No newline at end of file
fun ChatRoomsRepository.Order.isUnreadOnTop(): Boolean = this == ChatRoomsRepository.Order.UNREAD_ON_TOP_ACTIVITY
|| this == ChatRoomsRepository.Order.UNREAD_ON_TOP_NAME
...@@ -301,10 +301,10 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView { ...@@ -301,10 +301,10 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView {
this.isGroupByFavorites = isGroupByFavorites this.isGroupByFavorites = isGroupByFavorites
if (isSortByName) { if (isSortByName) {
viewModel.setQuery(Query.ByName(isGroupByType)) viewModel.setQuery(Query.ByName(isGroupByType, isUnreadOnTop))
changeSortByTitle(getString(R.string.msg_sort_by_name)) changeSortByTitle(getString(R.string.msg_sort_by_name))
} else { } else {
viewModel.setQuery(Query.ByActivity(isGroupByType)) viewModel.setQuery(Query.ByActivity(isGroupByType, isUnreadOnTop))
changeSortByTitle(getString(R.string.msg_sort_by_activity)) changeSortByTitle(getString(R.string.msg_sort_by_activity))
} }
} }
...@@ -324,9 +324,9 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView { ...@@ -324,9 +324,9 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView {
private fun showAllChats() { private fun showAllChats() {
if (isSortByName) { if (isSortByName) {
viewModel.setQuery(Query.ByName(isGroupByType)) viewModel.setQuery(Query.ByName(isGroupByType, isUnreadOnTop))
} else { } else {
viewModel.setQuery(Query.ByActivity(isGroupByType)) viewModel.setQuery(Query.ByActivity(isGroupByType, isUnreadOnTop))
} }
} }
......
...@@ -140,8 +140,10 @@ sealed class LoadingState { ...@@ -140,8 +140,10 @@ sealed class LoadingState {
} }
sealed class Query { sealed class Query {
data class ByActivity(val grouped: Boolean = false) : Query()
data class ByName(val grouped: Boolean = false) : Query() data class ByActivity(val grouped: Boolean = false, val unreadOnTop: Boolean = false) : Query()
data class ByName(val grouped: Boolean = false, val unreadOnTop: Boolean = false ) : Query()
data class Search(val query: String) : Query() data class Search(val query: String) : Query()
} }
...@@ -155,22 +157,44 @@ fun Query.isGrouped(): Boolean { ...@@ -155,22 +157,44 @@ fun Query.isGrouped(): Boolean {
} }
} }
fun Query.isUnreadOnTop(): Boolean {
return when(this) {
is Query.Search -> false
is Query.ByName -> unreadOnTop
is Query.ByActivity -> unreadOnTop
}
}
fun Query.asSortingOrder(): ChatRoomsRepository.Order { fun Query.asSortingOrder(): ChatRoomsRepository.Order {
return when(this) { return when(this) {
is Query.ByName -> { is Query.ByName -> {
if (grouped) { if (grouped && !unreadOnTop) {
ChatRoomsRepository.Order.GROUPED_NAME ChatRoomsRepository.Order.GROUPED_NAME
} else { }
else if(unreadOnTop && !grouped){
ChatRoomsRepository.Order.UNREAD_ON_TOP_NAME
}
else if(unreadOnTop && grouped){
ChatRoomsRepository.Order.UNREAD_ON_TOP_GROUPED_NAME
}
else {
ChatRoomsRepository.Order.NAME ChatRoomsRepository.Order.NAME
} }
} }
is Query.ByActivity -> { is Query.ByActivity -> {
if (grouped) { if (grouped && !unreadOnTop) {
ChatRoomsRepository.Order.GROUPED_ACTIVITY ChatRoomsRepository.Order.GROUPED_ACTIVITY
} else { }
else if(unreadOnTop && !grouped){
ChatRoomsRepository.Order.UNREAD_ON_TOP_ACTIVITY
}
else if(unreadOnTop && grouped){
ChatRoomsRepository.Order.UNREAD_ON_TOP_GROUPED_ACTIVITY
}
else {
ChatRoomsRepository.Order.ACTIVITY ChatRoomsRepository.Order.ACTIVITY
} }
} }
else -> throw IllegalArgumentException("Should be ByName or ByActivity") else -> throw IllegalArgumentException("Should be ByName or ByActivity")
} }
} }
\ No newline at end of file
...@@ -65,6 +65,54 @@ abstract class ChatRoomDao : BaseDao<ChatRoomEntity> { ...@@ -65,6 +65,54 @@ abstract class ChatRoomDao : BaseDao<ChatRoomEntity> {
""") """)
abstract fun getAllGrouped(): LiveData<List<ChatRoom>> abstract fun getAllGrouped(): LiveData<List<ChatRoom>>
@Transaction
@Query("""
$BASE_QUERY
$FILTER_NOT_OPENED
ORDER BY
$UNREAD,
CASE
WHEN lastMessageTimeStamp IS NOT NULL THEN lastMessageTimeStamp
ELSE updatedAt
END DESC
""")
abstract fun getAllUnread(): LiveData<List<ChatRoom>>
@Transaction
@Query("""
$BASE_QUERY
$FILTER_NOT_OPENED
ORDER BY
$UNREAD,
name COLLATE NOCASE
""")
abstract fun getAllAlphabeticallyUnread(): LiveData<List<ChatRoom>>
@Transaction
@Query("""
$BASE_QUERY
$FILTER_NOT_OPENED
ORDER BY
$TYPE_ORDER,
$UNREAD,
name COLLATE NOCASE
""")
abstract fun getAllAlphabeticallyGroupedUnread(): LiveData<List<ChatRoom>>
@Transaction
@Query("""
$BASE_QUERY
$FILTER_NOT_OPENED
ORDER BY
$TYPE_ORDER,
$UNREAD,
CASE
WHEN lastMessageTimeStamp IS NOT NULL THEN lastMessageTimeStamp
ELSE updatedAt
END DESC
""")
abstract fun getAllGroupedUnread(): LiveData<List<ChatRoom>>
@Transaction @Transaction
@Query(""" @Query("""
$BASE_QUERY $BASE_QUERY
...@@ -139,5 +187,11 @@ abstract class ChatRoomDao : BaseDao<ChatRoomEntity> { ...@@ -139,5 +187,11 @@ abstract class ChatRoomDao : BaseDao<ChatRoomEntity> {
ELSE 5 ELSE 5
END END
""" """
const val UNREAD = """
CASE
WHEN alert OR unread > 0 THEN 1
ELSE 2
END
"""
} }
} }
\ No newline at end of file
...@@ -26,7 +26,7 @@ object AndroidPermissionsHelper { ...@@ -26,7 +26,7 @@ object AndroidPermissionsHelper {
} }
fun hasCameraPermission(context: Context): Boolean { fun hasCameraPermission(context: Context): Boolean {
return AndroidPermissionsHelper.checkPermission(context, Manifest.permission.CAMERA) return checkPermission(context, Manifest.permission.CAMERA)
} }
fun getCameraPermission(fragment: Fragment) { fun getCameraPermission(fragment: Fragment) {
...@@ -50,10 +50,10 @@ object AndroidPermissionsHelper { ...@@ -50,10 +50,10 @@ object AndroidPermissionsHelper {
fun checkWritingPermission(context: Context) { fun checkWritingPermission(context: Context) {
if (context is ContextThemeWrapper) { if (context is ContextThemeWrapper) {
val activity = if (context.baseContext is Activity) context.baseContext as Activity else context as Activity val activity = if (context.baseContext is Activity) context.baseContext as Activity else context as Activity
AndroidPermissionsHelper.requestPermission( requestPermission(
activity, activity,
Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE,
AndroidPermissionsHelper.WRITE_EXTERNAL_STORAGE_CODE WRITE_EXTERNAL_STORAGE_CODE
) )
} }
} }
......
...@@ -3,6 +3,7 @@ package chat.rocket.android.profile.ui ...@@ -3,6 +3,7 @@ package chat.rocket.android.profile.ui
import DrawableHelper import DrawableHelper
import android.app.Activity import android.app.Activity
import android.content.Intent import android.content.Intent
import android.content.pm.PackageManager
import android.graphics.Bitmap import android.graphics.Bitmap
import android.os.Build import android.os.Build
import android.os.Bundle import android.os.Bundle
...@@ -21,6 +22,9 @@ import androidx.fragment.app.Fragment ...@@ -21,6 +22,9 @@ import androidx.fragment.app.Fragment
import chat.rocket.android.R import chat.rocket.android.R
import chat.rocket.android.analytics.AnalyticsManager import chat.rocket.android.analytics.AnalyticsManager
import chat.rocket.android.analytics.event.ScreenViewEvent import chat.rocket.android.analytics.event.ScreenViewEvent
import chat.rocket.android.helper.AndroidPermissionsHelper
import chat.rocket.android.helper.AndroidPermissionsHelper.getCameraPermission
import chat.rocket.android.helper.AndroidPermissionsHelper.hasCameraPermission
import chat.rocket.android.main.ui.MainActivity import chat.rocket.android.main.ui.MainActivity
import chat.rocket.android.profile.presentation.ProfilePresenter import chat.rocket.android.profile.presentation.ProfilePresenter
import chat.rocket.android.profile.presentation.ProfileView import chat.rocket.android.profile.presentation.ProfileView
...@@ -35,12 +39,15 @@ import chat.rocket.android.util.invalidateFirebaseToken ...@@ -35,12 +39,15 @@ import chat.rocket.android.util.invalidateFirebaseToken
import chat.rocket.common.model.UserStatus import chat.rocket.common.model.UserStatus
import chat.rocket.common.model.userStatusOf import chat.rocket.common.model.userStatusOf
import com.facebook.drawee.backends.pipeline.Fresco import com.facebook.drawee.backends.pipeline.Fresco
import com.google.android.material.snackbar.Snackbar
import dagger.android.support.AndroidSupportInjection import dagger.android.support.AndroidSupportInjection
import io.reactivex.disposables.CompositeDisposable import io.reactivex.disposables.CompositeDisposable
import io.reactivex.rxkotlin.Observables import io.reactivex.rxkotlin.Observables
import kotlinx.android.synthetic.main.app_bar.* import kotlinx.android.synthetic.main.app_bar.*
import kotlinx.android.synthetic.main.avatar_profile.* import kotlinx.android.synthetic.main.avatar_profile.*
import kotlinx.android.synthetic.main.fragment_profile.* import kotlinx.android.synthetic.main.fragment_profile.*
import kotlinx.android.synthetic.main.fragment_profile.view_dim
import kotlinx.android.synthetic.main.fragment_profile.view_loading
import kotlinx.android.synthetic.main.update_avatar_options.* import kotlinx.android.synthetic.main.update_avatar_options.*
import javax.inject.Inject import javax.inject.Inject
...@@ -52,8 +59,10 @@ private const val REQUEST_CODE_FOR_PERFORM_CAMERA = 2 ...@@ -52,8 +59,10 @@ private const val REQUEST_CODE_FOR_PERFORM_CAMERA = 2
fun newInstance() = ProfileFragment() fun newInstance() = ProfileFragment()
class ProfileFragment : Fragment(), ProfileView, ActionMode.Callback { class ProfileFragment : Fragment(), ProfileView, ActionMode.Callback {
@Inject lateinit var presenter: ProfilePresenter @Inject
@Inject lateinit var analyticsManager: AnalyticsManager lateinit var presenter: ProfilePresenter
@Inject
lateinit var analyticsManager: AnalyticsManager
private var currentStatus = "" private var currentStatus = ""
private var currentName = "" private var currentName = ""
private var currentUsername = "" private var currentUsername = ""
...@@ -223,7 +232,13 @@ class ProfileFragment : Fragment(), ProfileView, ActionMode.Callback { ...@@ -223,7 +232,13 @@ class ProfileFragment : Fragment(), ProfileView, ActionMode.Callback {
} }
button_take_a_photo.setOnClickListener { button_take_a_photo.setOnClickListener {
dispatchTakePicture(REQUEST_CODE_FOR_PERFORM_CAMERA) context?.let {
if (hasCameraPermission(it)) {
dispatchTakePicture(REQUEST_CODE_FOR_PERFORM_CAMERA)
} else {
getCameraPermission(this)
}
}
hideUpdateAvatarOptions() hideUpdateAvatarOptions()
} }
...@@ -331,4 +346,28 @@ class ProfileFragment : Fragment(), ProfileView, ActionMode.Callback { ...@@ -331,4 +346,28 @@ class ProfileFragment : Fragment(), ProfileView, ActionMode.Callback {
}.show() }.show()
} }
} }
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
when (requestCode) {
AndroidPermissionsHelper.CAMERA_CODE -> {
if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted
dispatchTakePicture(REQUEST_CODE_FOR_PERFORM_CAMERA)
} else {
// permission denied
Snackbar.make(
relative_layout,
R.string.msg_camera_permission_denied,
Snackbar.LENGTH_SHORT
).show()
}
return
}
}
}
} }
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
<string name="title_admin_panel">Панель админа</string> <string name="title_admin_panel">Панель админа</string>
<string name="title_password">Изменить пароль</string> <string name="title_password">Изменить пароль</string>
<string name="title_update_profile">Обновить профиль</string> <string name="title_update_profile">Обновить профиль</string>
<string name="title_choose_language">Choose Language</string> <!-- TODO Add translation --> <string name="title_choose_language">Изменить язык</string>
<string name="title_create_channel">Создать новый канал</string> <string name="title_create_channel">Создать новый канал</string>
<string name="title_channel_details">О канале</string> <string name="title_channel_details">О канале</string>
<string name="title_topic">Тема</string> <string name="title_topic">Тема</string>
...@@ -74,23 +74,23 @@ ...@@ -74,23 +74,23 @@
<string name="msg_delete_account">Удалить аккаунт</string> <string name="msg_delete_account">Удалить аккаунт</string>
<string name="msg_change_status">Изменить статус</string> <string name="msg_change_status">Изменить статус</string>
<string-array name="languages"> <!-- TODO Add translations --> <string-array name="languages">
<item>English</item> <item>Английский</item>
<item>Arabic</item> <item>Арабский</item>
<item>German</item> <item>Немецкий</item>
<item>Spanish</item> <item>Испанский</item>
<item>Persian</item> <item>Персидский</item>
<item>French</item> <item>Французский</item>
<item>Hindi (IN)</item> <item>Хинди (IN)</item>
<item>Italian</item> <item>Итальянский</item>
<item>Japanese</item> <item>Японский</item>
<item>Portuguese (BR)</item> <item>Португальский (BR)</item>
<item>Portuguese (PT)</item> <item>Португальский (PT)</item>
<item>Russian (RU)</item> <item>Русский (RU)</item>
<item>Turkish</item> <item>Турецкий</item>
<item>Ukrainian</item> <item>Украинский</item>
<item>Chinese (CN)</item> <item>Китайский (CN)</item>
<item>Chinese (TW)</item> <item>Китайский (TW)</item>
</string-array> </string-array>
<!-- Regular information messages --> <!-- Regular information messages -->
...@@ -203,7 +203,7 @@ ...@@ -203,7 +203,7 @@
<string name="msg_storage_permission_denied">Необходимо разрешение на использование хранилища</string> <string name="msg_storage_permission_denied">Необходимо разрешение на использование хранилища</string>
<string name="msg_server">Сервер</string> <string name="msg_server">Сервер</string>
<string name="msg_add_new_server">Добавить новый сервер</string> <string name="msg_add_new_server">Добавить новый сервер</string>
<string name="msg_directory">Директория</string> <string name="msg_directory">Каталог</string>
<!-- Create channel messages --> <!-- Create channel messages -->
<string name="msg_private_channel">Приватный</string> <string name="msg_private_channel">Приватный</string>
...@@ -344,7 +344,7 @@ ...@@ -344,7 +344,7 @@
<string name="msg_channels">Каналы</string> <string name="msg_channels">Каналы</string>
<string name="msg_users">Пользователи</string> <string name="msg_users">Пользователи</string>
<string name="msg_search_for_global_users">Поиск глобальных пользователей</string> <string name="msg_search_for_global_users">Поиск глобальных пользователей</string>
<string name="msg_search_for_global_users_description">При активации станет возможен поиск любого пользователя из других компаний или серверов.</string> <string name="msg_search_for_global_users_description">При активации станет возможен поиск пользователей на других серверах.</string>
<string name="header_private_groups">Приватные каналы</string> <string name="header_private_groups">Приватные каналы</string>
<string name="header_direct_messages">Личная переписка</string> <string name="header_direct_messages">Личная переписка</string>
<string name="header_live_chats">Живые чаты</string> <string name="header_live_chats">Живые чаты</string>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment