mirror of
https://github.com/ChronosX88/Influence.git
synced 2024-12-27 08:41:45 +00:00
Made global (in memory) avatar cache and round avatars in ChatActivity
This commit is contained in:
parent
6c83e7d9e0
commit
cebfb33ff8
@ -30,6 +30,8 @@ import androidx.room.Room;
|
||||
import com.instacart.library.truetime.TrueTime;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import io.github.chronosx88.influence.LoginCredentials;
|
||||
import io.github.chronosx88.influence.XMPPConnection;
|
||||
@ -49,6 +51,7 @@ public class AppHelper extends MultiDexApplication {
|
||||
private static LoginCredentials currentLoginCredentials;
|
||||
private static Handler mainUIThreadHandler;
|
||||
private static ServiceConnection serviceConnection;
|
||||
public final static Map<String, byte[]> avatarsCache = new ConcurrentHashMap<>();
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
@ -107,12 +110,14 @@ public class AppHelper extends MultiDexApplication {
|
||||
private static void initTrueTime() {
|
||||
new Thread(() -> {
|
||||
boolean isTrueTimeIsOn = false;
|
||||
while(!isTrueTimeIsOn) {
|
||||
int count = 0;
|
||||
while(!isTrueTimeIsOn && count <= 10) {
|
||||
try {
|
||||
TrueTime.build().withNtpHost(DEFAULT_NTP_SERVER).initialize();
|
||||
isTrueTimeIsOn = true;
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
|
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright 2019 ChronosX88
|
||||
*
|
||||
* 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 io.github.chronosx88.influence.helpers;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.amulyakhare.textdrawable.TextDrawable;
|
||||
import com.amulyakhare.textdrawable.util.ColorGenerator;
|
||||
import com.stfalcon.chatkit.commons.ImageLoader;
|
||||
|
||||
import org.jxmpp.jid.EntityBareJid;
|
||||
import org.jxmpp.jid.impl.JidCreate;
|
||||
import org.jxmpp.stringprep.XmppStringprepException;
|
||||
|
||||
import java9.util.concurrent.CompletableFuture;
|
||||
|
||||
public class AvatarImageLoader implements ImageLoader {
|
||||
@Override
|
||||
public void loadImage(ImageView imageView, @Nullable String url, @Nullable Object payload) {
|
||||
if(url.length() != 0) {
|
||||
if(AppHelper.avatarsCache.containsKey(url)) {
|
||||
byte[] avatarBytes = AppHelper.avatarsCache.get(url);
|
||||
Bitmap avatar = BitmapFactory.decodeByteArray(avatarBytes, 0, avatarBytes.length);
|
||||
imageView.setImageBitmap(avatar);
|
||||
return;
|
||||
}
|
||||
String firstLetter = Character.toString(Character.toUpperCase(url.charAt(0)));
|
||||
imageView.setImageDrawable(TextDrawable.builder()
|
||||
.beginConfig()
|
||||
.width(64)
|
||||
.height(64)
|
||||
.endConfig()
|
||||
.buildRound(firstLetter, ColorGenerator.MATERIAL.getColor(firstLetter)));
|
||||
CompletableFuture.supplyAsync(() -> {
|
||||
while (AppHelper.getXmppConnection() == null);
|
||||
while (AppHelper.getXmppConnection().isConnectionAlive() != true);
|
||||
EntityBareJid jid = null;
|
||||
try {
|
||||
jid = JidCreate.entityBareFrom(url);
|
||||
} catch (XmppStringprepException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return AppHelper.getXmppConnection().getAvatar(jid);
|
||||
}).thenAccept((avatarBytes) -> {
|
||||
AppHelper.getMainUIThread().post(() -> {
|
||||
if(avatarBytes != null) {
|
||||
Bitmap avatar = BitmapFactory.decodeByteArray(avatarBytes, 0, avatarBytes.length);
|
||||
imageView.setImageBitmap(avatar);
|
||||
AppHelper.avatarsCache.put(url, avatarBytes);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
@ -21,10 +21,12 @@ import com.amulyakhare.textdrawable.TextDrawable
|
||||
import com.amulyakhare.textdrawable.util.ColorGenerator
|
||||
import com.google.gson.Gson
|
||||
import com.stfalcon.chatkit.commons.ImageLoader
|
||||
import com.stfalcon.chatkit.messages.MessageHolders
|
||||
import com.stfalcon.chatkit.messages.MessagesListAdapter
|
||||
import io.github.chronosx88.influence.R
|
||||
import io.github.chronosx88.influence.contracts.CoreContracts
|
||||
import io.github.chronosx88.influence.helpers.AppHelper
|
||||
import io.github.chronosx88.influence.helpers.AvatarImageLoader
|
||||
import io.github.chronosx88.influence.helpers.LocalDBWrapper
|
||||
import io.github.chronosx88.influence.logic.ChatLogic
|
||||
import io.github.chronosx88.influence.models.GenericMessage
|
||||
@ -50,31 +52,9 @@ class ChatPresenter(private val view: CoreContracts.IChatViewContract, private v
|
||||
this.logic = ChatLogic(LocalDBWrapper.getChatByChatID(chatID)!!)
|
||||
this.chatEntity = LocalDBWrapper.getChatByChatID(chatID)
|
||||
gson = Gson()
|
||||
chatAdapter = MessagesListAdapter(AppHelper.getJid(), ImageLoader { imageView, url, _ ->
|
||||
val firstLetter = Character.toString(Character.toUpperCase(url!!.get(0)))
|
||||
imageView.setImageDrawable(TextDrawable.builder()
|
||||
.beginConfig()
|
||||
.width(64)
|
||||
.height(64)
|
||||
.endConfig()
|
||||
.buildRound(firstLetter, ColorGenerator.MATERIAL.getColor(firstLetter)))
|
||||
CompletableFuture.supplyAsync { while (AppHelper.getXmppConnection() == null) ;
|
||||
while (!AppHelper.getXmppConnection().isConnectionAlive) ;
|
||||
var jid: EntityBareJid? = null
|
||||
try {
|
||||
jid = JidCreate.entityBareFrom(url)
|
||||
} catch (e: XmppStringprepException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
||||
AppHelper.getXmppConnection().getAvatar(jid) }.thenAccept { avatarBytes -> AppHelper.getMainUIThread().post {
|
||||
if (avatarBytes != null) {
|
||||
val avatar = BitmapFactory.decodeByteArray(avatarBytes, 0, avatarBytes.size)
|
||||
imageView.setImageBitmap(avatar)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
val holdersConfig = MessageHolders()
|
||||
holdersConfig.setIncomingTextLayout(R.layout.item_incoming_text_message_custom)
|
||||
chatAdapter = MessagesListAdapter(AppHelper.getJid(), holdersConfig, AvatarImageLoader())
|
||||
view.setAdapter(chatAdapter)
|
||||
EventBus.getDefault().register(this)
|
||||
}
|
||||
|
@ -43,6 +43,7 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
import io.github.chronosx88.influence.R;
|
||||
import io.github.chronosx88.influence.contracts.CoreContracts;
|
||||
import io.github.chronosx88.influence.helpers.AppHelper;
|
||||
import io.github.chronosx88.influence.helpers.AvatarImageLoader;
|
||||
import io.github.chronosx88.influence.helpers.LocalDBWrapper;
|
||||
import io.github.chronosx88.influence.logic.DialogListLogic;
|
||||
import io.github.chronosx88.influence.models.GenericDialog;
|
||||
@ -60,42 +61,7 @@ public class DialogListPresenter implements CoreContracts.IDialogListPresenterCo
|
||||
private ConcurrentHashMap<String, byte[]> avatarsMap = new ConcurrentHashMap<>();
|
||||
private CoreContracts.IChatListViewContract view;
|
||||
private CoreContracts.IDialogListLogicContract logic;
|
||||
private DialogsListAdapter<GenericDialog> dialogListAdapter = new DialogsListAdapter<>(R.layout.item_dialog_custom, (imageView, url, payload) -> {
|
||||
if(url.length() != 0) {
|
||||
if(avatarsMap.containsKey(url)) {
|
||||
byte[] avatarBytes = avatarsMap.get(url);
|
||||
Bitmap avatar = BitmapFactory.decodeByteArray(avatarBytes, 0, avatarBytes.length);
|
||||
imageView.setImageBitmap(avatar);
|
||||
return;
|
||||
}
|
||||
String firstLetter = Character.toString(Character.toUpperCase(url.charAt(0)));
|
||||
imageView.setImageDrawable(TextDrawable.builder()
|
||||
.beginConfig()
|
||||
.width(64)
|
||||
.height(64)
|
||||
.endConfig()
|
||||
.buildRound(firstLetter, ColorGenerator.MATERIAL.getColor(firstLetter)));
|
||||
CompletableFuture.supplyAsync(() -> {
|
||||
while (AppHelper.getXmppConnection() == null);
|
||||
while (AppHelper.getXmppConnection().isConnectionAlive() != true);
|
||||
EntityBareJid jid = null;
|
||||
try {
|
||||
jid = JidCreate.entityBareFrom(url);
|
||||
} catch (XmppStringprepException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return AppHelper.getXmppConnection().getAvatar(jid);
|
||||
}).thenAccept((avatarBytes) -> {
|
||||
AppHelper.getMainUIThread().post(() -> {
|
||||
if(avatarBytes != null) {
|
||||
Bitmap avatar = BitmapFactory.decodeByteArray(avatarBytes, 0, avatarBytes.length);
|
||||
imageView.setImageBitmap(avatar);
|
||||
avatarsMap.put(url, avatarBytes);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
private DialogsListAdapter<GenericDialog> dialogListAdapter = new DialogsListAdapter<>(R.layout.item_dialog_custom, new AvatarImageLoader());
|
||||
private Comparator<GenericDialog> dialogComparator = (dialog1, dialog2) -> Long.compare(dialog2.getLastMessage().getCreatedAt().getTime(), dialog1.getLastMessage().getCreatedAt().getTime());
|
||||
|
||||
public DialogListPresenter(CoreContracts.IChatListViewContract view) {
|
||||
@ -147,7 +113,7 @@ public class DialogListPresenter implements CoreContracts.IDialogListPresenterCo
|
||||
Intent intent = new Intent(AppHelper.getContext(), ChatActivity.class);
|
||||
intent.putExtra("chatID", chatID);
|
||||
intent.putExtra("chatName", LocalDBWrapper.getChatByChatID(chatID).chatName);
|
||||
intent.putExtra("chatAvatar", avatarsMap.get(chatID));
|
||||
intent.putExtra("chatAvatar", AppHelper.avatarsCache.get(chatID));
|
||||
view.startActivity(intent);
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,66 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright 2019 ChronosX88
|
||||
~
|
||||
~ 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.
|
||||
-->
|
||||
|
||||
<RelativeLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_marginTop="8dp">
|
||||
|
||||
<de.hdodenhof.circleimageview.CircleImageView
|
||||
android:id="@id/messageUserAvatar"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_marginRight="8dp"/>
|
||||
|
||||
<com.google.android.flexbox.FlexboxLayout
|
||||
android:id="@id/bubble"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="@dimen/message_incoming_bubble_margin_right"
|
||||
android:layout_marginRight="@dimen/message_incoming_bubble_margin_right"
|
||||
android:layout_toEndOf="@id/messageUserAvatar"
|
||||
android:layout_toRightOf="@id/messageUserAvatar"
|
||||
android:orientation="vertical"
|
||||
app:alignContent="stretch"
|
||||
app:alignItems="stretch"
|
||||
app:flexWrap="wrap"
|
||||
app:justifyContent="flex_end">
|
||||
|
||||
<TextView
|
||||
android:id="@id/messageText"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<TextView
|
||||
android:id="@id/messageTime"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/messageText"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:layout_marginStart="8dp"
|
||||
app:layout_alignSelf="center"/>
|
||||
|
||||
</com.google.android.flexbox.FlexboxLayout>
|
||||
|
||||
</RelativeLayout>
|
Loading…
Reference in New Issue
Block a user