mirror of
https://github.com/nextcloud/talk-android
synced 2025-07-10 14:24:05 +01:00
Better layouts
This commit is contained in:
parent
436bdeb49f
commit
b9503a0869
@ -107,7 +107,8 @@ android {
|
|||||||
}
|
}
|
||||||
|
|
||||||
release {
|
release {
|
||||||
minifyEnabled false
|
minifyEnabled true
|
||||||
|
shrinkResources true
|
||||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -199,18 +199,21 @@ class ConversationItem(
|
|||||||
holder.dialogLastMessage.setText(R.string.nc_no_messages_yet)
|
holder.dialogLastMessage.setText(R.string.nc_no_messages_yet)
|
||||||
}
|
}
|
||||||
|
|
||||||
val conversationDrawable: Drawable? = Images().getImageForConversation(context, model)
|
holder.dialogAvatar.apply {
|
||||||
if (conversationDrawable != null) {
|
val conversationDrawable: Drawable? = Images().getImageForConversation(context, model)
|
||||||
holder.dialogAvatar.load(conversationDrawable)
|
|
||||||
} else {
|
if (conversationDrawable != null) {
|
||||||
holder.dialogAvatar.load(
|
load(conversationDrawable)
|
||||||
ApiUtils.getUrlForAvatarWithName(
|
} else {
|
||||||
|
if (model.name?.contains("marco") == false) {
|
||||||
|
load(ApiUtils.getUrlForAvatarWithName(
|
||||||
user.baseUrl,
|
user.baseUrl,
|
||||||
model.name, R.dimen.avatar_size
|
model.name, R.dimen.avatar_size))
|
||||||
)
|
{
|
||||||
) {
|
addHeader("Authorization", user.getCredentials())
|
||||||
addHeader("Authorization", user.getCredentials())
|
transformations(CircleCropTransformation())
|
||||||
transformations(CircleCropTransformation())
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -227,6 +230,7 @@ class ConversationItem(
|
|||||||
view: View,
|
view: View,
|
||||||
adapter: FlexibleAdapter<*>
|
adapter: FlexibleAdapter<*>
|
||||||
) : FlexibleViewHolder(view, adapter), LayoutContainer {
|
) : FlexibleViewHolder(view, adapter), LayoutContainer {
|
||||||
|
|
||||||
override val containerView: View?
|
override val containerView: View?
|
||||||
get() = itemView
|
get() = itemView
|
||||||
}
|
}
|
||||||
|
@ -35,6 +35,7 @@ import androidx.work.PeriodicWorkRequest
|
|||||||
import androidx.work.WorkManager
|
import androidx.work.WorkManager
|
||||||
import coil.Coil
|
import coil.Coil
|
||||||
import coil.ImageLoader
|
import coil.ImageLoader
|
||||||
|
import coil.util.CoilLogger
|
||||||
import com.bluelinelabs.logansquare.LoganSquare
|
import com.bluelinelabs.logansquare.LoganSquare
|
||||||
import com.nextcloud.talk.BuildConfig
|
import com.nextcloud.talk.BuildConfig
|
||||||
import com.nextcloud.talk.components.filebrowser.webdav.DavUtils
|
import com.nextcloud.talk.components.filebrowser.webdav.DavUtils
|
||||||
@ -127,6 +128,8 @@ class NextcloudTalkApplication : Application(), LifecycleObserver {
|
|||||||
startKoin()
|
startKoin()
|
||||||
DavUtils.registerCustomFactories()
|
DavUtils.registerCustomFactories()
|
||||||
|
|
||||||
|
CoilLogger.setLevel(Log.DEBUG)
|
||||||
|
CoilLogger.setEnabled(true)// Enable logging to the standard Android log.
|
||||||
Coil.setDefaultImageLoader(imageLoader)
|
Coil.setDefaultImageLoader(imageLoader)
|
||||||
migrateUsers()
|
migrateUsers()
|
||||||
|
|
||||||
|
@ -120,7 +120,7 @@ fun createOkHttpClient(
|
|||||||
httpClient.retryOnConnectionFailure(true)
|
httpClient.retryOnConnectionFailure(true)
|
||||||
httpClient.hostnameVerifier(magicTrustManager.getHostnameVerifier(OkHostnameVerifier.INSTANCE))
|
httpClient.hostnameVerifier(magicTrustManager.getHostnameVerifier(OkHostnameVerifier.INSTANCE))
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.N) {
|
if (SDK_INT == Build.VERSION_CODES.N) {
|
||||||
val suites = sslSocketFactory.defaultCipherSuites
|
val suites = sslSocketFactory.defaultCipherSuites
|
||||||
val tlsSpec = ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS).cipherSuites(*suites).build()
|
val tlsSpec = ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS).cipherSuites(*suites).build()
|
||||||
httpClient.connectionSpecs(listOf(tlsSpec, ConnectionSpec.CLEARTEXT))
|
httpClient.connectionSpecs(listOf(tlsSpec, ConnectionSpec.CLEARTEXT))
|
||||||
@ -145,7 +145,7 @@ fun createOkHttpClient(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
httpClient.addNetworkInterceptor { chain ->
|
httpClient.addInterceptor { chain ->
|
||||||
var response = chain.proceed(chain.request())
|
var response = chain.proceed(chain.request())
|
||||||
|
|
||||||
if (response.request().url().encodedPath().contains("/avatar/")) {
|
if (response.request().url().encodedPath().contains("/avatar/")) {
|
||||||
@ -291,7 +291,6 @@ fun createImageLoader(
|
|||||||
): ImageLoader {
|
): ImageLoader {
|
||||||
return ImageLoader(androidApplication) {
|
return ImageLoader(androidApplication) {
|
||||||
availableMemoryPercentage(0.5)
|
availableMemoryPercentage(0.5)
|
||||||
bitmapPoolPercentage(0.5)
|
|
||||||
crossfade(true)
|
crossfade(true)
|
||||||
okHttpClient(okHttpClient)
|
okHttpClient(okHttpClient)
|
||||||
componentRegistry {
|
componentRegistry {
|
||||||
|
@ -76,7 +76,7 @@ class ConversationsListView : BaseView(), OnQueryTextListener,
|
|||||||
private lateinit var viewModel: ConversationsListViewModel
|
private lateinit var viewModel: ConversationsListViewModel
|
||||||
val factory: ConversationListViewModelFactory by inject()
|
val factory: ConversationListViewModelFactory by inject()
|
||||||
|
|
||||||
private val recyclerViewAdapter = FlexibleAdapter(mutableListOf(), null, false)
|
private val recyclerViewAdapter = FlexibleAdapter(mutableListOf(), this, false)
|
||||||
|
|
||||||
private var searchItem: MenuItem? = null
|
private var searchItem: MenuItem? = null
|
||||||
private var settingsItem: MenuItem? = null
|
private var settingsItem: MenuItem? = null
|
||||||
@ -164,6 +164,30 @@ class ConversationsListView : BaseView(), OnQueryTextListener,
|
|||||||
actionBar?.show()
|
actionBar?.show()
|
||||||
|
|
||||||
viewModel = viewModelProvider(factory).get(ConversationsListViewModel::class.java)
|
viewModel = viewModelProvider(factory).get(ConversationsListViewModel::class.java)
|
||||||
|
|
||||||
|
val view = super.onCreateView(inflater, container)
|
||||||
|
|
||||||
|
view.apply {
|
||||||
|
recyclerView.initRecyclerView(
|
||||||
|
SmoothScrollLinearLayoutManager(activity), recyclerViewAdapter, false)
|
||||||
|
recyclerViewAdapter.fastScroller = fast_scroller
|
||||||
|
swipeRefreshLayoutView.setOnRefreshListener {
|
||||||
|
view.swipeRefreshLayoutView.isRefreshing = false
|
||||||
|
viewModel.loadConversations()
|
||||||
|
}
|
||||||
|
swipeRefreshLayoutView.setColorSchemeResources(R.color.colorPrimary)
|
||||||
|
fast_scroller.setBubbleTextCreator { position ->
|
||||||
|
var displayName =
|
||||||
|
(recyclerViewAdapter.getItem(position) as ConversationItem).model.displayName
|
||||||
|
|
||||||
|
if (displayName!!.length > 8) {
|
||||||
|
displayName = displayName.substring(0, 4) + "..."
|
||||||
|
}
|
||||||
|
|
||||||
|
displayName
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
viewModel.apply {
|
viewModel.apply {
|
||||||
currentUserAvatar.observe(this@ConversationsListView, Observer { value ->
|
currentUserAvatar.observe(this@ConversationsListView, Observer { value ->
|
||||||
settingsItem?.icon = value
|
settingsItem?.icon = value
|
||||||
@ -173,15 +197,15 @@ class ConversationsListView : BaseView(), OnQueryTextListener,
|
|||||||
val isListEmpty = it.isNullOrEmpty()
|
val isListEmpty = it.isNullOrEmpty()
|
||||||
|
|
||||||
if (isListEmpty) {
|
if (isListEmpty) {
|
||||||
view?.stateWithMessageView?.errorStateTextView?.text =
|
view.stateWithMessageView?.errorStateTextView?.text =
|
||||||
resources?.getText(R.string.nc_conversations_empty)
|
resources?.getText(R.string.nc_conversations_empty)
|
||||||
view?.stateWithMessageView?.errorStateImageView?.setImageResource(drawable.ic_logo)
|
view.stateWithMessageView?.errorStateImageView?.setImageResource(drawable.ic_logo)
|
||||||
}
|
}
|
||||||
|
|
||||||
view?.stateWithMessageView?.visibility = if (isListEmpty && networkStateLiveData.value != LOADING) View.VISIBLE else View.GONE
|
view.stateWithMessageView?.visibility = if (isListEmpty && networkStateLiveData.value != LOADING) View.VISIBLE else View.GONE
|
||||||
|
|
||||||
if (view?.floatingActionButton?.isShown == false) {
|
if (view.floatingActionButton?.isShown == false) {
|
||||||
view?.floatingActionButton?.show()
|
view.floatingActionButton?.show()
|
||||||
}
|
}
|
||||||
|
|
||||||
searchItem?.isVisible = !isListEmpty
|
searchItem?.isVisible = !isListEmpty
|
||||||
@ -206,34 +230,34 @@ class ConversationsListView : BaseView(), OnQueryTextListener,
|
|||||||
networkStateLiveData.observe(this@ConversationsListView, Observer { value ->
|
networkStateLiveData.observe(this@ConversationsListView, Observer { value ->
|
||||||
when (value) {
|
when (value) {
|
||||||
LOADING -> {
|
LOADING -> {
|
||||||
view?.post {
|
view.post {
|
||||||
view?.loadingStateView?.visibility = View.VISIBLE
|
view.loadingStateView?.visibility = View.VISIBLE
|
||||||
view?.dataStateView?.visibility = View.GONE
|
view.recyclerView?.visibility = View.GONE
|
||||||
view?.stateWithMessageView?.visibility = View.GONE
|
view.stateWithMessageView?.visibility = View.GONE
|
||||||
view?.floatingActionButton?.visibility = View.GONE
|
view.floatingActionButton?.visibility = View.GONE
|
||||||
}
|
}
|
||||||
searchItem?.isVisible = false
|
searchItem?.isVisible = false
|
||||||
}
|
}
|
||||||
LOADED -> {
|
LOADED -> {
|
||||||
// awesome, but we delegate the magic stuff to the data handler
|
// awesome, but we delegate the magic stuff to the data handler
|
||||||
view?.post {
|
view.post {
|
||||||
view?.loadingStateView?.visibility = View.GONE
|
view.loadingStateView?.visibility = View.GONE
|
||||||
view?.dataStateView?.visibility = View.VISIBLE
|
view.recyclerView?.visibility = View.VISIBLE
|
||||||
view?.stateWithMessageView?.visibility = if (recyclerViewAdapter.isEmpty) View.VISIBLE else View.GONE
|
view.stateWithMessageView?.visibility = if (recyclerViewAdapter.isEmpty) View.VISIBLE else View.GONE
|
||||||
view?.floatingActionButton?.visibility = View.VISIBLE
|
view.floatingActionButton?.visibility = View.VISIBLE
|
||||||
if (view?.floatingActionButton?.isShown == false) {
|
if (view.floatingActionButton?.isShown == false) {
|
||||||
view?.floatingActionButton?.show()
|
view.floatingActionButton?.show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
searchItem?.isVisible = !recyclerViewAdapter.isEmpty
|
searchItem?.isVisible = !recyclerViewAdapter.isEmpty
|
||||||
}
|
}
|
||||||
FAILED -> {
|
FAILED -> {
|
||||||
// probably offline, so what? :)
|
// probably offline, so what? :)
|
||||||
view?.post {
|
view.post {
|
||||||
view?.loadingStateView?.visibility = View.GONE
|
view.loadingStateView?.visibility = View.GONE
|
||||||
view?.dataStateView?.visibility = View.VISIBLE
|
view.recyclerView?.visibility = View.VISIBLE
|
||||||
view?.floatingActionButton?.visibility = View.GONE
|
view.floatingActionButton?.visibility = View.GONE
|
||||||
view?.stateWithMessageView?.visibility = if (recyclerViewAdapter.isEmpty) View.VISIBLE else View.GONE
|
view.stateWithMessageView?.visibility = if (recyclerViewAdapter.isEmpty) View.VISIBLE else View.GONE
|
||||||
}
|
}
|
||||||
searchItem?.isVisible = !recyclerViewAdapter.isEmpty
|
searchItem?.isVisible = !recyclerViewAdapter.isEmpty
|
||||||
}
|
}
|
||||||
@ -249,9 +273,7 @@ class ConversationsListView : BaseView(), OnQueryTextListener,
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return view
|
||||||
|
|
||||||
return super.onCreateView(inflater, container)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getLayoutId(): Int {
|
override fun getLayoutId(): Int {
|
||||||
@ -366,30 +388,6 @@ class ConversationsListView : BaseView(), OnQueryTextListener,
|
|||||||
|
|
||||||
override fun onAttach(view: View) {
|
override fun onAttach(view: View) {
|
||||||
super.onAttach(view)
|
super.onAttach(view)
|
||||||
view.recyclerView.initRecyclerView(
|
|
||||||
SmoothScrollLinearLayoutManager(view.context), recyclerViewAdapter, false
|
|
||||||
)
|
|
||||||
|
|
||||||
recyclerViewAdapter.fastScroller = view.fast_scroller
|
|
||||||
recyclerViewAdapter.mItemClickListener = this
|
|
||||||
recyclerViewAdapter.mItemLongClickListener = this
|
|
||||||
|
|
||||||
view.swipeRefreshLayoutView.setOnRefreshListener {
|
|
||||||
view.swipeRefreshLayoutView.isRefreshing = false
|
|
||||||
viewModel.loadConversations()
|
|
||||||
}
|
|
||||||
view.swipeRefreshLayoutView.setColorSchemeResources(R.color.colorPrimary)
|
|
||||||
|
|
||||||
view.fast_scroller.setBubbleTextCreator { position ->
|
|
||||||
var displayName =
|
|
||||||
(recyclerViewAdapter.getItem(position) as ConversationItem).model.displayName
|
|
||||||
|
|
||||||
if (displayName!!.length > 8) {
|
|
||||||
displayName = displayName.substring(0, 4) + "..."
|
|
||||||
}
|
|
||||||
|
|
||||||
displayName
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onItemLongClick(position: Int) {
|
override fun onItemLongClick(position: Int) {
|
||||||
|
@ -27,7 +27,7 @@ fun RecyclerView.initRecyclerView(
|
|||||||
adapter: RecyclerView.Adapter<out RecyclerView.ViewHolder>,
|
adapter: RecyclerView.Adapter<out RecyclerView.ViewHolder>,
|
||||||
hasFixedSize: Boolean = true
|
hasFixedSize: Boolean = true
|
||||||
) {
|
) {
|
||||||
this.layoutManager = layoutManager
|
|
||||||
this.adapter = adapter
|
this.adapter = adapter
|
||||||
|
this.layoutManager = layoutManager
|
||||||
setHasFixedSize(hasFixedSize)
|
setHasFixedSize(hasFixedSize)
|
||||||
}
|
}
|
@ -100,7 +100,7 @@ object DisplayUtils {
|
|||||||
fun getRoundedDrawable(drawable: Drawable?): Drawable {
|
fun getRoundedDrawable(drawable: Drawable?): Drawable {
|
||||||
val bitmap = getBitmap(drawable!!)
|
val bitmap = getBitmap(drawable!!)
|
||||||
val drawable = runBlocking {
|
val drawable = runBlocking {
|
||||||
return@runBlocking BitmapDrawable(CircleCropTransformation().transform(BitmapPool(10000), bitmap, OriginalSize))
|
return@runBlocking BitmapDrawable(CircleCropTransformation().transform(BitmapPool(0), bitmap, OriginalSize))
|
||||||
}
|
}
|
||||||
|
|
||||||
return drawable
|
return drawable
|
||||||
|
@ -24,53 +24,41 @@
|
|||||||
android:id="@+id/generic_rv_layout"
|
android:id="@+id/generic_rv_layout"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:animateLayoutChanges="true"
|
android:animateLayoutChanges="true">
|
||||||
>
|
|
||||||
|
|
||||||
<include
|
<include
|
||||||
layout="@layout/view_states"
|
layout="@layout/view_states"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent" />
|
||||||
/>
|
|
||||||
|
|
||||||
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||||
android:id="@+id/swipeRefreshLayoutView"
|
android:id="@+id/swipeRefreshLayoutView"
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:visibility="visible"
|
|
||||||
app:layout_behavior="com.nextcloud.talk.utils.FABAwareScrollingViewBehavior"
|
|
||||||
>
|
|
||||||
|
|
||||||
<FrameLayout
|
|
||||||
android:id="@+id/dataStateView"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:visibility="invisible"
|
android:visibility="visible"
|
||||||
>
|
app:layout_behavior="com.nextcloud.talk.utils.FABAwareScrollingViewBehavior">
|
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
|
||||||
android:id="@+id/recyclerView"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
tools:listitem="@layout/rv_item_conversation_with_last_message"
|
|
||||||
/>
|
|
||||||
|
|
||||||
</FrameLayout>
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/recyclerView"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
tools:listitem="@layout/rv_item_conversation_with_last_message" />
|
||||||
|
|
||||||
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
|
||||||
|
|
||||||
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
||||||
android:id="@+id/floatingActionButton"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="bottom|end"
|
|
||||||
android:layout_margin="16dp"
|
|
||||||
android:visibility="gone"
|
|
||||||
app:srcCompat="@drawable/ic_add_white_24px"
|
|
||||||
app:tint="@color/white"
|
|
||||||
app:backgroundTint="@color/colorPrimary"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<include layout="@layout/fast_scroller" />
|
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||||
|
android:id="@+id/floatingActionButton"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="bottom|end"
|
||||||
|
android:layout_margin="16dp"
|
||||||
|
android:visibility="gone"
|
||||||
|
app:backgroundTint="@color/colorPrimary"
|
||||||
|
app:srcCompat="@drawable/ic_add_white_24px"
|
||||||
|
app:tint="@color/white" />
|
||||||
|
|
||||||
|
<include layout="@layout/fast_scroller" />
|
||||||
|
|
||||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||||
|
Loading…
Reference in New Issue
Block a user