Party Part 2 - Memberlist / Fix Avatars

This commit is contained in:
Negue 2015-09-23 22:39:04 +02:00
parent 560669da95
commit 1588f856a5
20 changed files with 626 additions and 104 deletions

View file

@ -13,10 +13,10 @@
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="18" />
/>
<uses-permission
android:name="android.permission.READ_EXTERNAL_STORAGE"
android:maxSdkVersion="18" />
/>
<application
android:name=".HabiticaApplication"

View file

@ -74,7 +74,7 @@
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/design/22.2.1/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/gridlayout-v7/22.2.1/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/recyclerview-v7/22.2.1/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/support-v4/22.2.1/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/support-v4/23.0.1/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.crashlytics.sdk.android/answers/1.2.0/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.crashlytics.sdk.android/beta/1.1.2/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.crashlytics.sdk.android/crashlytics-core/2.3.0/jars" />
@ -107,8 +107,8 @@
</content>
<orderEntry type="jdk" jdkName="Android API 22 Platform" jdkType="Android SDK" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" exported="" name="library-1.0.19" level="project" />
<orderEntry type="library" exported="" name="gson-2.3.1" level="project" />
<orderEntry type="library" exported="" name="library-1.0.19" level="project" />
<orderEntry type="library" exported="" name="commons-io-2.4" level="project" />
<orderEntry type="library" exported="" name="okhttp-2.3.0" level="project" />
<orderEntry type="library" exported="" name="rxjava-1.0.10" level="project" />
@ -122,30 +122,29 @@
<orderEntry type="library" exported="" name="library-1.1.4" level="project" />
<orderEntry type="library" exported="" name="org.abego.treelayout.core-1.0.1" level="project" />
<orderEntry type="library" exported="" name="DBFlow-2.2.1" level="project" />
<orderEntry type="library" exported="" name="support-v4-23.0.1" level="project" />
<orderEntry type="library" exported="" name="compilerCommon-1.0-rc1" level="project" />
<orderEntry type="library" exported="" name="compiler-1.0-rc1" level="project" />
<orderEntry type="library" exported="" name="mimecraft-1.1.1" level="project" />
<orderEntry type="library" exported="" name="library-2.4.0" level="project" />
<orderEntry type="library" exported="" name="guava-18.0" level="project" />
<orderEntry type="library" exported="" name="iconics-1.1.0" level="project" />
<orderEntry type="library" exported="" name="support-v4-22.2.1" level="project" />
<orderEntry type="library" exported="" name="auto-service-1.0-rc2" level="project" />
<orderEntry type="library" exported="" name="baseLibrary-1.0-rc1" level="project" />
<orderEntry type="library" exported="" name="fabric-1.3.1" level="project" />
<orderEntry type="library" exported="" name="beta-1.1.2" level="project" />
<orderEntry type="library" exported="" name="gridlayout-v7-22.2.1" level="project" />
<orderEntry type="library" exported="" name="commons-codec-1.10" level="project" />
<orderEntry type="library" exported="" name="javawriter-2.5.0" level="project" />
<orderEntry type="library" exported="" name="commons-codec-1.10" level="project" />
<orderEntry type="library" exported="" name="commons-lang3-3.3.2" level="project" />
<orderEntry type="library" exported="" name="kotlin-stdlib-0.12.613" level="project" />
<orderEntry type="library" exported="" name="design-22.2.1" level="project" />
<orderEntry type="library" exported="" name="cardview-v7-22.2.0" level="project" />
<orderEntry type="library" exported="" name="kotlin-runtime-0.12.613" level="project" />
<orderEntry type="library" exported="" name="DBFlow-Compiler-2.2.1" level="project" />
<orderEntry type="library" exported="" name="kotlin-runtime-0.12.613" level="project" />
<orderEntry type="library" exported="" name="answers-1.2.0" level="project" />
<orderEntry type="library" exported="" name="picasso-2.5.2" level="project" />
<orderEntry type="library" exported="" name="recyclerview-v7-22.2.1" level="project" />
<orderEntry type="library" exported="" name="support-annotations-22.2.1" level="project" />
<orderEntry type="library" exported="" name="retrofit-1.9.0" level="project" />
<orderEntry type="library" exported="" name="DBFlow-Core-2.2.1" level="project" />
<orderEntry type="library" exported="" name="materialdrawer-3.0.8" level="project" />
@ -154,6 +153,7 @@
<orderEntry type="library" exported="" name="antlr-runtime-3.5.2" level="project" />
<orderEntry type="library" exported="" name="butterknife-6.1.0" level="project" />
<orderEntry type="library" exported="" name="okio-1.3.0" level="project" />
<orderEntry type="library" exported="" name="support-annotations-23.0.1" level="project" />
<orderEntry type="library" exported="" name="adapters-1.0-rc1" level="project" />
<orderEntry type="library" exported="" name="okhttp-urlconnection-2.3.0" level="project" />
<orderEntry type="library" exported="" name="eventbus-2.4.0" level="project" />

View file

@ -1,4 +1,21 @@
[
{
"name": "Version 0.0.4",
"items":[
{
"type": "F",
"title": "Party :)"
},
{
"type": "B",
"title": "Avatar-Drawing: Position without a mount/met"
},
{
"type": "N",
"title": "Generated avatar images are now cached"
}
]
},
{
"name": "Version 0.0.3",
"items":[

View file

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.RecyclerView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbarSize="3dp"
android:scrollbarThumbVertical="@color/md_grey_500"
android:scrollbars="vertical" />

View file

@ -0,0 +1,80 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="5dp"
android:orientation="horizontal">
<ImageView
android:id="@+id/avatar"
android:layout_width="80dp"
android:layout_height="80dp" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="6"
android:orientation="vertical">
<TextView
android:id="@+id/username"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="username"
android:textSize="@dimen/abc_text_size_title_material"
android:textStyle="bold" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="@+id/user_lvl"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_weight="1"
android:text="lvl" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="right">
<LinearLayout
android:id="@+id/class_background_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_margin="10dp"
android:background="@drawable/layout_rounded_bg">
<TextView
android:id="@+id/class_label"
style="@style/ChatMessageUserTextViewStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:ellipsize="middle"
android:lines="1"
android:text="class" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
<include
android:id="@+id/hpBar"
layout="@layout/value_bar" />
</LinearLayout>
</LinearLayout>
</android.support.v7.widget.CardView>

View file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="class_healer">#FFFF00</color>
<color name="class_warrior">#FF0000</color>
<color name="class_wizard">#0000FF</color>
<color name="class_rogue">#7736205D</color>
</resources>

View file

@ -9,13 +9,20 @@ import com.habitrpg.android.habitica.events.commands.CreateTagCommand;
import com.habitrpg.android.habitica.prefs.PrefsActivity;
import com.habitrpg.android.habitica.ui.MainDrawerBuilder;
import com.habitrpg.android.habitica.ui.fragments.ChatListFragment;
import com.habitrpg.android.habitica.ui.fragments.PartyInformationFragment;
import com.habitrpg.android.habitica.ui.fragments.PartyMemberListFragment;
import com.magicmicky.habitrpgwrapper.lib.models.Group;
import com.magicmicky.habitrpgwrapper.lib.models.HabitRPGUser;
import com.raizlabs.android.dbflow.sql.builder.Condition;
import com.raizlabs.android.dbflow.sql.language.Select;
import java.util.ArrayList;
import java.util.HashMap;
import butterknife.InjectView;
import retrofit.Callback;
import retrofit.RetrofitError;
import retrofit.client.Response;
public class PartyActivity extends AvatarActivityBase implements AppBarLayout.OnOffsetChangedListener {
@ -44,8 +51,9 @@ public class PartyActivity extends AvatarActivityBase implements AppBarLayout.On
mAPIHelper = new APIHelper(this, hostConfig);
updateUserAvatars();
}
@Override
@ -74,9 +82,18 @@ public class PartyActivity extends AvatarActivityBase implements AppBarLayout.On
Fragment fragment;
switch (position) {
case 1:
case 0: {
fragment = new PartyInformationFragment();
break;
}
case 1: {
fragment = new ChatListFragment(PartyActivity.this, "party", mAPIHelper, User, false);
break;
}
case 2: {
fragment = new PartyMemberListFragment(PartyActivity.this, mAPIHelper.apiService);
break;
}
default:
fragment = new Fragment();
}
@ -125,10 +142,10 @@ public class PartyActivity extends AvatarActivityBase implements AppBarLayout.On
public void onOffsetChanged(AppBarLayout appBarLayout, int i) {
Fragment fragment = fragmentDictionary.get(viewPager.getCurrentItem());
if(!(fragment instanceof ChatListFragment))
if (!(fragment instanceof ChatListFragment))
return;
ChatListFragment chatFragment = (ChatListFragment)fragment ;
ChatListFragment chatFragment = (ChatListFragment) fragment;
// Disable Refresh if Header is collapsed

View file

@ -56,17 +56,28 @@ public class AvatarWithBarsViewModel {
public void UpdateData(HabitRPGUser user)
{
Stats stats = user.getStats();
SetValueBar(hpBar, stats.getHp().floatValue(), stats.getMaxHealth(), context.getString(R.string.HP_default), context.getResources().getColor(R.color.hpColor));
SetHpBarData(hpBar, stats, context);
SetValueBar(xpBar, stats.getExp().floatValue(), stats.getToNextLevel(), context.getString(R.string.XP_default), context.getResources().getColor(R.color.xpColor));
SetValueBar(mpBar, stats.getMp().floatValue(), stats.getMaxMP(), context.getString(R.string.MP_default), context.getResources().getColor(R.color.mpColor));
new UserPicture(user, this.context).setPictureOn(image);
}
public static void SetHpBarData(ValueBarBinding valueBar, Stats stats, Context ctx)
{
int maxHP = stats.getMaxHealth();
if(maxHP == 0)
{
maxHP = 50;
}
SetValueBar(valueBar, stats.getHp().floatValue(), maxHP, ctx.getString(R.string.HP_default), ctx.getResources().getColor(R.color.hpColor));
}
// Layout_Weight don't accepts 0.7/0.3 to have 70% filled instead it shows the 30% , so I had to switch the values
// but on a 1.0/0.0 which switches to 0.0/1.0 it shows the blank part full size...
private void SetValueBar(ValueBarBinding valueBar, float value, float valueMax, String description, int color)
private static void SetValueBar(ValueBarBinding valueBar, float value, float valueMax, String description, int color)
{
double percent = Math.min(1, value / valueMax);

View file

@ -40,7 +40,7 @@ import de.greenrobot.event.EventBus;
/**
* Created by Negue on 20.08.2015.
*/
public class TavernRecyclerViewAdapter extends RecyclerView.Adapter<TavernRecyclerViewAdapter.TavernRecyclerViewHolder> {
public class ChatRecyclerViewAdapter extends RecyclerView.Adapter<ChatRecyclerViewAdapter.ChatRecyclerViewHolder> {
static final int TYPE_DANIEL = 0;
static final int TYPE_NEW_MESSAGE = 1;
static final int TYPE_MESSAGE = 2;
@ -48,15 +48,23 @@ public class TavernRecyclerViewAdapter extends RecyclerView.Adapter<TavernRecycl
private List<ChatMessage> messages;
private Context viewContext;
private String uuid;
private String groupId;
private boolean isTavern;
public TavernRecyclerViewAdapter(List<ChatMessage> messages, Context viewContext, String uuid) {
public ChatRecyclerViewAdapter(List<ChatMessage> messages, Context viewContext, String uuid, String groupId, boolean isTavern) {
this.messages = messages;
this.viewContext = viewContext;
this.uuid = uuid;
this.groupId = groupId;
this.isTavern = isTavern;
}
@Override
public int getItemViewType(int position) {
if(!isTavern){
return TYPE_MESSAGE;
}
switch (position) {
case 0: {
return TYPE_DANIEL;
@ -71,19 +79,17 @@ public class TavernRecyclerViewAdapter extends RecyclerView.Adapter<TavernRecycl
}
@Override
public TavernRecyclerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
public ChatRecyclerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
int rLayout = R.layout.tavern_chat_item;
switch (viewType) {
case TYPE_DANIEL: {
rLayout = R.layout.tavern_daniel_item;
break;
}
case TYPE_NEW_MESSAGE: {
rLayout = R.layout.tavern_chat_new_entry_item;
break;
}
}
@ -91,11 +97,16 @@ public class TavernRecyclerViewAdapter extends RecyclerView.Adapter<TavernRecycl
View view = LayoutInflater.from(parent.getContext())
.inflate(rLayout, parent, false);
return new TavernRecyclerViewHolder(view, viewType, viewContext, uuid, "habitrpg");
return new ChatRecyclerViewHolder(view, viewType, viewContext, uuid, groupId);
}
@Override
public void onBindViewHolder(TavernRecyclerViewHolder holder, int position) {
public void onBindViewHolder(ChatRecyclerViewHolder holder, int position) {
if(!isTavern){
holder.bind(messages.get(position));
return;
}
if (position > 1) {
holder.bind(messages.get(position - 2));
}
@ -103,10 +114,10 @@ public class TavernRecyclerViewAdapter extends RecyclerView.Adapter<TavernRecycl
@Override
public int getItemCount() {
return messages.size() + 2;
return messages.size() + (isTavern ? 2 : 0);
}
public class TavernRecyclerViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, PopupMenu.OnMenuItemClickListener {
public class ChatRecyclerViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, PopupMenu.OnMenuItemClickListener {
private int layoutType;
private String uuid;
@ -157,7 +168,7 @@ public class TavernRecyclerViewAdapter extends RecyclerView.Adapter<TavernRecycl
Context context;
Resources res;
public TavernRecyclerViewHolder(View itemView, int layoutType, Context viewContext, String currentUserId, String groupId) {
public ChatRecyclerViewHolder(View itemView, int layoutType, Context viewContext, String currentUserId, String groupId) {
super(itemView);
this.layoutType = layoutType;
this.uuid = currentUserId;
@ -208,6 +219,10 @@ public class TavernRecyclerViewAdapter extends RecyclerView.Adapter<TavernRecycl
DataBindingUtils.setRoundedBackgroundInt(userBackground, msg.getContributorColor());
if(msg.user == null || msg.user.equals("")){
msg.user = "system";
}
userLabel.setText(msg.user);
DataBindingUtils.setForegroundTintColor(userLabel, msg.getContributorForegroundColor());

View file

@ -0,0 +1,126 @@
package com.habitrpg.android.habitica.ui.adapter;
import android.content.res.Resources;
import android.databinding.DataBindingUtil;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.habitrpg.android.habitica.R;
import com.habitrpg.android.habitica.databinding.ValueBarBinding;
import com.habitrpg.android.habitica.ui.AvatarWithBarsViewModel;
import com.habitrpg.android.habitica.ui.helpers.ViewHelper;
import com.habitrpg.android.habitica.userpicture.UserPicture;
import com.magicmicky.habitrpgwrapper.lib.models.HabitRPGUser;
import java.lang.annotation.Inherited;
import java.util.ArrayList;
import butterknife.ButterKnife;
import butterknife.InjectView;
/**
* Created by Negue on 22.09.2015.
*/
public class PartyMemberRecyclerViewAdapter extends RecyclerView.Adapter<PartyMemberRecyclerViewAdapter.MemberViewHolder> {
private ArrayList<HabitRPGUser> memberList;
public void setMemberList(ArrayList<HabitRPGUser> memberList) {
this.memberList = memberList;
this.notifyDataSetChanged();
}
@Override
public MemberViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.party_member, parent, false);
return new MemberViewHolder(view);
}
@Override
public void onBindViewHolder(MemberViewHolder holder, int position) {
holder.bind(memberList.get(position));
}
@Override
public int getItemCount() {
return memberList == null ? 0 : memberList.size();
}
class MemberViewHolder extends RecyclerView.ViewHolder {
@InjectView(R.id.avatar)
ImageView imageView;
@InjectView(R.id.username)
TextView userName;
@InjectView(R.id.user_lvl)
TextView lvl;
@InjectView(R.id.class_label)
TextView classLabel;
@InjectView(R.id.class_background_layout)
View classBackground;
ValueBarBinding hpBar;
Resources resources;
public MemberViewHolder(View itemView) {
super(itemView);
ButterKnife.inject(this, itemView);
View hpBarView = itemView.findViewById(R.id.hpBar);
hpBar = DataBindingUtil.bind(hpBarView);
resources = itemView.getResources();
}
public void bind(HabitRPGUser user) {
android.content.Context ctx = itemView.getContext();
UserPicture userPicture = new UserPicture(user, ctx);
userPicture.setPictureOn(imageView);
AvatarWithBarsViewModel.SetHpBarData(hpBar, user.getStats(), ctx);
lvl.setText("LVL " + user.getStats().getLvl());
classLabel.setText(user.getStats()._class.toString());
switch (user.getStats()._class) {
case healer: {
ViewHelper.SetBackgroundTint(classBackground, resources.getColor(R.color.class_healer));
break;
}
case warrior: {
ViewHelper.SetBackgroundTint(classBackground, resources.getColor(R.color.class_warrior));
break;
}
case rogue: {
ViewHelper.SetBackgroundTint(classBackground, resources.getColor(R.color.class_rogue));
break;
}
case wizard: {
ViewHelper.SetBackgroundTint(classBackground, resources.getColor(R.color.class_wizard));
break;
}
}
userName.setText(user.getProfile().getName());
}
}
}

View file

@ -21,7 +21,7 @@ import com.habitrpg.android.habitica.events.commands.FlagChatMessageCommand;
import com.habitrpg.android.habitica.events.commands.SendNewGroupMessageCommand;
import com.habitrpg.android.habitica.events.commands.ToggleInnCommand;
import com.habitrpg.android.habitica.events.commands.ToggleLikeMessageCommand;
import com.habitrpg.android.habitica.ui.adapter.TavernRecyclerViewAdapter;
import com.habitrpg.android.habitica.ui.adapter.ChatRecyclerViewAdapter;
import com.magicmicky.habitrpgwrapper.lib.models.ChatMessage;
import com.magicmicky.habitrpgwrapper.lib.models.HabitRPGUser;
import com.magicmicky.habitrpgwrapper.lib.models.PostChatMessageResult;
@ -127,7 +127,7 @@ public class ChatListFragment extends Fragment implements SwipeRefreshLayout.OnR
}
}
TavernRecyclerViewAdapter tavernAdapter = new TavernRecyclerViewAdapter(chatMessages, ctx, userId);
ChatRecyclerViewAdapter tavernAdapter = new ChatRecyclerViewAdapter(chatMessages, ctx, userId, groupId, isTavern);
mRecyclerView.setAdapter(tavernAdapter);

View file

@ -0,0 +1,9 @@
package com.habitrpg.android.habitica.ui.fragments;
import android.support.v4.app.Fragment;
/**
* Created by Negue on 16.09.2015.
*/
public class PartyInformationFragment extends Fragment {
}

View file

@ -0,0 +1,80 @@
package com.habitrpg.android.habitica.ui.fragments;
import android.content.Context;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.habitrpg.android.habitica.R;
import com.habitrpg.android.habitica.ui.adapter.PartyMemberRecyclerViewAdapter;
import com.magicmicky.habitrpgwrapper.lib.api.ApiService;
import com.magicmicky.habitrpgwrapper.lib.models.Group;
import butterknife.ButterKnife;
import butterknife.InjectView;
import retrofit.Callback;
import retrofit.RetrofitError;
import retrofit.client.Response;
/**
* Created by Negue on 15.09.2015.
*/
public class PartyMemberListFragment extends Fragment {
private Context ctx;
private ApiService apiService;
private PartyMemberRecyclerViewAdapter viewAdapter;
public PartyMemberListFragment(Context ctx, ApiService apiService){
this.ctx = ctx;
this.apiService = apiService;
viewAdapter = new PartyMemberRecyclerViewAdapter();
}
private View view;
@InjectView(R.id.recyclerView)
RecyclerView mRecyclerView;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
if (view == null)
view = inflater.inflate(R.layout.fragment_party_memberlist, container, false);
return view;
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
ButterKnife.inject(this, view);
mRecyclerView.setLayoutManager(new LinearLayoutManager(ctx));
mRecyclerView.setAdapter(viewAdapter);
// Get the full group data
apiService.getGroup("party", new Callback<Group>() {
@Override
public void success(Group group, Response response) {
viewAdapter.setMemberList(group.members);
}
@Override
public void failure(RetrofitError error) {
}
});
}
}

View file

@ -5,7 +5,6 @@ import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.support.v7.widget.CardView;
import android.util.Log;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.Transformation;
@ -16,7 +15,6 @@ import android.widget.LinearLayout;
import android.widget.TextView;
import com.habitrpg.android.habitica.R;
import com.habitrpg.android.habitica.ui.helpers.ViewHelper;
import com.squareup.picasso.Picasso;
/**
@ -73,8 +71,6 @@ public class DataBindingUtils {
public static void setLayoutWeight(View view, float weight) {
LinearLayout.LayoutParams layout = (LinearLayout.LayoutParams)view.getLayoutParams();
Log.d("setLayoutWeight", weight + "");
layout.weight = weight;
view.setLayoutParams(layout);
@ -82,6 +78,11 @@ public class DataBindingUtils {
@BindingAdapter("app:layout_weight_anim")
public static void setLayoutWeightAnim(View view, float weight) {
if(weight == 0.0f || weight == 1.0f){
setLayoutWeight(view, weight);
return;
}
LayoutWeightAnimation anim = new LayoutWeightAnimation(view, weight);
anim.setDuration(1250);

View file

@ -0,0 +1,52 @@
package com.habitrpg.android.habitica.userpicture;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Environment;
import java.io.File;
import java.io.FileOutputStream;
public class BitmapUtils {
public static String getSavePath() {
String path;
if (hasSDCard()) {
path = Environment.getExternalStorageDirectory().getAbsolutePath();
} else {
path = Environment.getDownloadCacheDirectory().getAbsolutePath();
}
return path+"/HabiticaImageCache";
}
public static Bitmap loadFromFile(String filename) {
try {
filename = getSavePath() +"/"+ filename;
File f = new File(filename);
if (!f.exists()) { return null; }
Bitmap tmp = BitmapFactory.decodeFile(filename);
return tmp;
} catch (Exception e) {
return null;
}
}
public static void saveToFile(String filename,Bitmap bmp) {
try {
File myDir = new File(getSavePath());
boolean res = myDir.mkdirs();
filename = getSavePath() +"/"+ filename;
FileOutputStream out = new FileOutputStream(filename);
bmp.compress(Bitmap.CompressFormat.PNG, 100, out);
out.flush();
out.close();
} catch(Exception e) {}
}
public static boolean hasSDCard() {
String status = Environment.getExternalStorageState();
return status.equals(Environment.MEDIA_MOUNTED);
}
}

View file

@ -7,12 +7,15 @@ import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.util.Log;
import android.widget.ImageView;
import com.magicmicky.habitrpgwrapper.lib.models.HabitRPGUser;
import com.squareup.picasso.Picasso;
import com.squareup.picasso.Target;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
@ -29,6 +32,8 @@ public class UserPicture {
private boolean hasBackground, hasMount, hasPet;
private String currentCacheFileName;
List layers = new ArrayList();
public UserPicture(HabitRPGUser user, Context context) {
@ -36,21 +41,16 @@ public class UserPicture {
this.context = context;
}
public void addTask(){
numOfTasks.incrementAndGet();
}
public void removeTask(){
numOfTasks.decrementAndGet();
}
public void allTasksComplete(){
if(this.numOfTasks.get() == 0){
BitmapFactory.Options o = new BitmapFactory.Options();
o.inScaled = false;
Bitmap res = Bitmap.createBitmap(140, 147, Bitmap.Config.ARGB_8888);
Bitmap res = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas myCanvas = new Canvas(res);
Integer layerNumber = 0;
for (Object layer : this.layers) {
@ -60,41 +60,95 @@ public class UserPicture {
}
layerNumber++;
}
BitmapUtils.saveToFile(currentCacheFileName, res);
this.imageView.setImageBitmap(res);
}
}
public void setPictureOn(ImageView imageView) {
this.imageView = imageView;
List<String> layerNames = this.user.getAvatarLayerNames();
if (this.user.getItems().getCurrentMount() != null) {
layerNames.add(0, "Mount_Body_" + this.user.getItems().getCurrentMount());
layerNames.add("Mount_Head_" + this.user.getItems().getCurrentMount());
String mountName = this.user.getItems().getCurrentMount();
if (mountName != null && !mountName.isEmpty()) {
layerNames.add(0, "Mount_Body_" + mountName);
layerNames.add("Mount_Head_" + mountName);
this.hasMount = true;
}
if (this.user.getItems().getCurrentPet() != null) {
layerNames.add("Pet-" + this.user.getItems().getCurrentPet());
String petName = this.user.getItems().getCurrentPet();
if (petName != null && !petName.isEmpty()) {
layerNames.add("Pet-" + petName);
this.hasPet = true;
}
if (this.user.getPreferences().getBackground() != null) {
layerNames.add(0, "background_" + this.user.getPreferences().getBackground());
String backgroundName = this.user.getPreferences().getBackground();
if (backgroundName != null && !backgroundName.isEmpty()) {
layerNames.add(0, "background_" + backgroundName);
this.hasBackground = true;
}
// get layer hash value
String fullLayerString = "";
for(String l : layerNames){
fullLayerString = fullLayerString.concat(l);
}
String layersHash = generateHashCode(fullLayerString);
currentCacheFileName = layersHash.concat(".png");
// does it already exist?
Bitmap cache = BitmapUtils.loadFromFile(currentCacheFileName);
// yes => load image to bitmap
if(cache != null){
imageView.setImageBitmap(cache);
return;
}
// no => generate it
Integer layerNumber = 0;
this.numOfTasks.set(layerNames.size());
for (String layer : layerNames) {
layers.add(0);
SpriteTarget target = new SpriteTarget(layerNumber);
SpriteTarget target = new SpriteTarget(layerNumber, layer);
Picasso.with(this.context).load("https://habitica-assets.s3.amazonaws.com/mobileApp/images/"+ layer +".png").into(target);
layerNumber = layerNumber + 1;
}
}
private static String generateHashCode(String value){
MessageDigest md = null;
byte[] digest = new byte[0];
try {
md = MessageDigest.getInstance("MD5");
md.update(value.getBytes());
digest = md.digest();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return bytesToHex(digest);
}
final protected static char[] hexArray = "0123456789ABCDEF".toCharArray();
public static String bytesToHex(byte[] bytes) {
char[] hexChars = new char[bytes.length * 2];
for ( int j = 0; j < bytes.length; j++ ) {
int v = bytes[j] & 0xFF;
hexChars[j * 2] = hexArray[v >>> 4];
hexChars[j * 2 + 1] = hexArray[v & 0x0F];
}
return new String(hexChars);
}
private void modifyCanvas(Bitmap img, Canvas canvas, Integer layerNumber) {
Paint paint = new Paint();
paint.setFilterBitmap(false);
@ -127,9 +181,11 @@ public class UserPicture {
private class SpriteTarget implements Target {
private Integer layerNumber;
private String layer;
public SpriteTarget(Integer layerNumber) {
public SpriteTarget(Integer layerNumber, String layer) {
this.layerNumber = layerNumber;
this.layer = layer;
}
@Override
@ -141,6 +197,8 @@ public class UserPicture {
@Override
public void onBitmapFailed(Drawable errorDrawable) {
Log.w("SpriteTarget", layer + " not on S3");
removeTask();
allTasksComplete();
}
@ -150,4 +208,8 @@ public class UserPicture {
}
}
}
}

View file

@ -2,6 +2,7 @@ package com.magicmicky.habitrpgwrapper.lib.api;
import com.magicmicky.habitrpgwrapper.lib.models.ChatMessage;
import com.magicmicky.habitrpgwrapper.lib.models.ContentResult;
import com.magicmicky.habitrpgwrapper.lib.models.Group;
import com.magicmicky.habitrpgwrapper.lib.models.HabitRPGUser;
import com.magicmicky.habitrpgwrapper.lib.models.PostChatMessageResult;
import com.magicmicky.habitrpgwrapper.lib.models.Status;
@ -11,8 +12,8 @@ import com.magicmicky.habitrpgwrapper.lib.models.UserAuth;
import com.magicmicky.habitrpgwrapper.lib.models.UserAuthResponse;
import com.magicmicky.habitrpgwrapper.lib.models.tasks.ItemData;
import com.magicmicky.habitrpgwrapper.lib.models.tasks.Task;
import com.squareup.okhttp.Call;
import java.util.ArrayList;
import java.util.List;
import retrofit.Callback;
@ -87,6 +88,12 @@ public interface ApiService {
/* Group API */
@GET("/groups")
void listGroups(@Query("type") String type, Callback<ArrayList<Group>> cb);
@GET("/groups/{gid}")
void getGroup(@Path("gid") String groupId, Callback<Group> cb);
@GET("/groups/{gid}/chat")
void listGroupChat(@Path("gid") String groupId, Callback<List<ChatMessage>> cb);

View file

@ -0,0 +1,41 @@
package com.magicmicky.habitrpgwrapper.lib.models;
import com.google.gson.annotations.SerializedName;
import com.raizlabs.android.dbflow.structure.BaseModel;
import java.util.ArrayList;
/**
* Created by Negue on 16.09.2015.
*/
public class Group extends BaseModel {
@SerializedName("_id")
public String id;
public double balance;
public String description;
// TODO Leader
// GET /groups?type={0} => leader is string
// GET /groups/{gid} => leader is user-object
public String name;
public int memberCount;
public String type;
public String logo;
public Quest quest;
public ArrayList<ChatMessage> chat;
public ArrayList<HabitRPGUser> members;
public int challengeCount;
// TODO Challenges
}

View file

@ -55,7 +55,7 @@ public class HabitRPGUser extends BaseModel {
@ForeignKey(references = {@ForeignKeyReference(columnName = "party_id",
columnType = String.class,
foreignColumnName = "id")})
private Party party;
private UserParty party;
@Column
@ -116,11 +116,11 @@ public class HabitRPGUser extends BaseModel {
this.profile = profile;
}
public Party getParty() {
public UserParty getParty() {
return party;
}
public void setParty(Party party) {
public void setParty(UserParty party) {
this.party = party;
}
@ -211,8 +211,10 @@ public class HabitRPGUser extends BaseModel {
layerNames.add("head_0");
if (outfit != null) {
if (outfit.getArmor() != null && !outfit.getArmor().equals("armor_base_0")) {
layerNames.add(prefs.getSize() + "_armor_" + outfit.getArmor());
String armor = outfit.getArmor();
if (armor != null && !armor.equals("armor_base_0")) {
layerNames.add(prefs.getSize() + "_" + armor);
}
if (outfit.getBody() != null && !outfit.getBody().equals("body_base_0")) {
layerNames.add(outfit.getBody());
@ -221,10 +223,13 @@ public class HabitRPGUser extends BaseModel {
Preferences.Hair hair = prefs.getHair();
if (hair != null) {
if (hair.getBase() > 0) {layerNames.add("hair_base_"+hair.getBase() + hair.getColor());}
if (hair.getBangs() > 0) {layerNames.add("hair_bangs_"+hair.getBangs() + hair.getColor());}
if (hair.getMustache() > 0) {layerNames.add("hair_mustache_"+hair.getMustache() + hair.getColor());}
if (hair.getBeard() > 0) {layerNames.add("hair_beard_"+hair.getBeard() + hair.getColor());}
String hairColor = hair.getColor();
if (hair.getBase() > 0) {layerNames.add("hair_base_"+hair.getBase() +"_" + hairColor);}
if (hair.getBangs() > 0) {layerNames.add("hair_bangs_"+hair.getBangs() +"_" + hairColor);}
if (hair.getMustache() > 0) {layerNames.add("hair_mustache_"+hair.getMustache() +"_" + hairColor);}
if (hair.getBeard() > 0) {layerNames.add("hair_beard_"+hair.getBeard() +"_" + hairColor);}
}
if (outfit != null) {

View file

@ -1,5 +1,6 @@
package com.magicmicky.habitrpgwrapper.lib.models;
import com.google.gson.annotations.SerializedName;
import com.habitrpg.android.habitica.HabitDatabase;
import com.raizlabs.android.dbflow.annotation.Column;
import com.raizlabs.android.dbflow.annotation.ForeignKey;
@ -9,74 +10,38 @@ import com.raizlabs.android.dbflow.annotation.Table;
import com.raizlabs.android.dbflow.structure.BaseModel;
/**
* Created by MagicMicky on 16/03/14.
* Created by Negue on 16.09.2015.
*/
@Table(databaseName = HabitDatabase.NAME)
public class Party extends BaseModel {
public class UserParty extends BaseModel {
@Column
@PrimaryKey
@SerializedName("_id")
public String id; //id
@Column
private String invitation;
@Column
private String lastMessageSeen;
@Column
private boolean leader;
@Column
@ForeignKey(references = {@ForeignKeyReference(columnName = "quest_id",
columnType = String.class,
foreignColumnName = "key")})
private Quest quest;
@Column
private String order;//Order to display ppl
public Party() {
@Column
private String orderAscending;//Order type
public UserParty() {
}
public Party(String id, String invitation, String lastMessageSeen, boolean leader, Quest quest, String order) {
public UserParty(String id, Quest quest, String order, String orderAscending) {
this.id = id;
this.invitation = invitation;
this.lastMessageSeen = lastMessageSeen;
this.leader = leader;
this.quest = quest;
this.order = order;
this.orderAscending = orderAscending;
}
public String getInvitation() {
return invitation;
}
public void setInvitation(String invitation) {
this.invitation = invitation;
}
public String getLastMessageSeen() {
return lastMessageSeen;
}
public void setLastMessageSeen(String lastMessageSeen) {
this.lastMessageSeen = lastMessageSeen;
}
public boolean getLeader() {
return leader;
}
public void setLeader(boolean leader) {
this.leader = leader;
}
public Quest getQuest() {
return quest;
}
public void setQuest(Quest quest) {
this.quest = quest;
}
public String getOrder() {
return order;
@ -86,4 +51,20 @@ public class Party extends BaseModel {
this.order = order;
}
public String getOrderAscending() {
return orderAscending;
}
public void setOrderAscending(String order) {
this.orderAscending = order;
}
public Quest getQuest() {
return quest;
}
public void setQuest(Quest quest) {
this.quest = quest;
}
}