List Tavern Messages, Send / Delete them, Toggle Sleep

This commit is contained in:
Negue 2015-08-30 19:56:46 +02:00
parent b26e48c104
commit 4f44bd44b5
55 changed files with 877 additions and 49 deletions

View file

@ -2,10 +2,10 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.habitrpg.android.habitica"
android:versionCode="2"
android:versionName="0.0.2" >
android:versionName="0.0.2">
<uses-sdk
android:minSdkVersion="13"
android:minSdkVersion="14"
android:targetSdkVersion="22" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
@ -23,11 +23,11 @@
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
android:theme="@style/AppTheme">
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:windowSoftInputMode="stateHidden|adjustResize" >
android:windowSoftInputMode="stateHidden|adjustResize">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
@ -37,7 +37,7 @@
<activity
android:name=".prefs.PrefsActivity"
android:label="@string/PS_param_title"
android:theme="@style/AppThemeWithActionBar" >
android:theme="@style/AppThemeWithActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
</intent-filter>
@ -46,7 +46,7 @@
android:name=".LoginActivity"
android:label="@string/LoginActivityName"
android:theme="@style/AppThemeWithActionBarBlackText"
android:windowSoftInputMode="adjustResize" >
android:windowSoftInputMode="adjustResize">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
</intent-filter>
@ -55,7 +55,7 @@
<receiver
android:name=".widget.SimpleWidget"
android:icon="@mipmap/ic_launcher"
android:label="Habitica Simple Widget" >
android:label="Habitica Simple Widget">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
@ -78,7 +78,7 @@
android:name=".TaskFormActivity"
android:label="@string/title_activity_task_form"
android:parentActivityName=".MainActivity"
android:theme="@style/AppThemeWithActionBarBlackText" >
android:theme="@style/AppThemeWithActionBarBlackText">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.habitrpg.android.habitica.MainActivity" />

View file

@ -113,8 +113,8 @@
<orderEntry type="library" exported="" name="gson-2.3.1" level="project" />
<orderEntry type="library" exported="" name="library-1.0.18" 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="kenburnsview-1.0.6" level="project" />
<orderEntry type="library" exported="" name="okhttp-2.3.0" level="project" />
<orderEntry type="library" exported="" name="rxjava-1.0.10" level="project" />
<orderEntry type="library" exported="" name="antlr4-4.5" level="project" />
<orderEntry type="library" exported="" name="crashlytics-core-2.3.0" level="project" />
@ -130,8 +130,8 @@
<orderEntry type="library" exported="" name="DBFlow-2.2.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="library-2.4.0" 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" />
@ -142,8 +142,8 @@
<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-lang3-3.3.2" level="project" />
<orderEntry type="library" exported="" name="kotlin-stdlib-0.12.613" level="project" />
<orderEntry type="library" exported="" name="commons-lang3-3.3.2" level="project" />
<orderEntry type="library" exported="" name="design-22.2.1" level="project" />
<orderEntry type="library" exported="" name="cardview-v7-22.2.1" level="project" />
<orderEntry type="library" exported="" name="kotlin-runtime-0.12.613" level="project" />

View file

@ -1,6 +1,15 @@
[
{
"name": "Verison 0.0.2",
"name": "Version 0.0.3",
"items":[
{
"type": "F",
"title": "Tavern :)"
}
]
},
{
"name": "Version 0.0.2",
"items": [
{
"type": "F",

View file

@ -98,10 +98,15 @@ android {
release
}
dexOptions{
preDexLibraries = false
}
buildTypes {
debug {
applicationIdSuffix ".debug"
debuggable true
}
release {
signingConfig signingConfigs.release

Binary file not shown.

After

Width:  |  Height:  |  Size: 172 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 161 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 282 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 334 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 133 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 115 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 188 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 244 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 209 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 156 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 285 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 162 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 390 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 294 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 200 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 385 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 222 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 523 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 384 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 243 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 494 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 315 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 656 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 5 KiB

View file

@ -1,37 +1,47 @@
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:id="@+id/drawer_layout"
tools:context=".TavernActivity">
<LinearLayout
android:id="@+id/layout_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:fitsSystemWindows="true"
android:layout_marginTop="25dp">
android:orientation="vertical">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:minHeight="?attr/actionBarSize"
android:background="?attr/colorPrimary" />
/>
<!-- As the main content view, the view below consumes the entire
space available using match_parent in both dimensions. -->
<FrameLayout
<LinearLayout
android:id="@+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white">
android:background="@color/white"
android:orientation="vertical">
<TextView android:text="Text" android:layout_width="wrap_content"
<include
android:id="@+id/avatar"
layout="@layout/avatar_with_bars"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</FrameLayout>
<android.support.v7.widget.RecyclerView
android:id="@+id/tavern.list"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
</LinearLayout>
</android.support.v4.widget.DrawerLayout>

View file

@ -12,7 +12,8 @@
android:orientation="horizontal"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingEnd="@dimen/activity_horizontal_margin"
android:paddingTop="8dp">
android:paddingTop="8dp"
android:background="@color/brand">
<ImageView
android:id="@+id/IMG_ProfilePicture"

View file

@ -0,0 +1,75 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<import type="com.magicmicky.habitrpgwrapper.lib.models.ChatMessage" />
<variable
name="msg"
type="ChatMessage" />
</data>
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:layout_columnWeight="5"
android:layout_gravity="center|left"
android:background="@drawable/layout_rounded_bg"
app:rounded_background_int="@{msg.getContributorColor()}">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="5dp"
style="@style/ChatMessageUserTextViewStyle"
android:text="@{msg.user}"
app:foregroundColor="@{msg.getContributorForegroundColor()}" />
</LinearLayout>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_columnSpan="2"
android:layout_marginLeft="15dp"
android:layout_marginRight="15dp"
android:layout_marginTop="5dp"
android:layout_weight="8"
android:text="@{msg.text}" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_column="1"
android:layout_columnWeight="5"
android:layout_gravity="right"
android:layout_margin="5dp"
android:layout_row="0">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center|right"
android:text="@{msg.getAgoString()}" />
<ImageView
android:id="@+id/btn_options"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:layout_margin="5dp"
android:layout_weight="1"
android:src="@drawable/ic_action_more_vert" />
</LinearLayout>
</GridLayout>
</layout>

View file

@ -0,0 +1,36 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="7dp"
android:text="Chat"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="@color/material_drawer_primary_text" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.rengwuxian.materialedittext.MaterialEditText
android:id="@+id/edit.new.message.text"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:hint="Write Message"
app:met_floatingLabel="normal"
android:layout_weight="1" />
<Button
android:id="@+id/btn.send.message"
android:layout_width="50dp"
android:layout_height="50dp" />
</LinearLayout>
</LinearLayout>

View file

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto">
<ImageView
android:layout_width="wrap_content"
android:layout_height="120dp"
android:src="@drawable/npc_daniel"
android:layout_margin="10dp"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center|center_horizontal">
<Button
android:id="@+id/btn.toggle.inn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Sleep"
android:layout_gravity="center"
android:backgroundTint="@color/brand"/>
</LinearLayout>
</LinearLayout>

View file

@ -0,0 +1,28 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/menu.chat.copy.as.todo"
android:icon="@drawable/ic_action_launch"
android:title="Copy as ToDo" />
<item
android:id="@+id/menu.chat.send.pm"
android:icon="@drawable/ic_action_chat"
android:title="Send PM" />
<group>
<item
android:id="@+id/menu.chat.flag"
android:icon="@drawable/ic_action_warning"
android:showAsAction="always|withText"
android:title="Flag" />
<item
android:id="@+id/menu.chat.delete"
android:icon="@drawable/ic_action_delete_white_24"
android:title="Delete" />
</group>
</menu>

View file

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="contributor.0">#aaa</color>
<color name="contributor.1">#f57a9d</color>
<color name="contributor.2">#b93030</color>
<color name="contributor.3">#ff3300</color>
<color name="contributor.4">#ff9500</color>
<color name="contributor.5">#fff700</color>
<color name="contributor.6">#5eff00</color>
<color name="contributor.7">#00aaff</color>
<color name="contributor.mod">#130ead</color>
<color name="contributor.staff">#88108f</color>
<color name="contributor.npc">#000</color>
<color name="contributor.npc.font">#00FF00</color>
</resources>

View file

@ -32,8 +32,9 @@
<item name="material_drawer_selected_text">@color/brand</item>
<item name="material_drawer_header_selection_text">@color/material_drawer_header_selection_text</item>
<item name="popupMenuStyle">@style/PopupTheme</item>
<item name="actionOverflowMenuStyle">@style/PopupTheme</item>
<item name="android:popupMenuStyle">@style/PopupTheme</item>
</style>
<style name="AppThemeWithOwnActionBar" parent="AppTheme">
@ -58,6 +59,8 @@
<item name="android:popupBackground">@color/accent_color</item>
</style>
<style name="CardText">
<item name="android:textSize">@dimen/card_small_text</item>
<item name="android:textColor">@color/card_text</item>
@ -107,4 +110,10 @@
<item name="color">@color/drawerArrowColor</item>
</style>
<style name="ChatMessageUserTextViewStyle">
<item name="android:shadowColor">#000000</item>
<item name="android:shadowDx">1</item>
<item name="android:shadowDy">1</item>
<item name="android:shadowRadius">1</item>
</style>
</resources>

View file

@ -29,6 +29,7 @@ import com.habitrpg.android.habitica.events.TaskLongPressedEvent;
import com.habitrpg.android.habitica.events.TaskSaveEvent;
import com.habitrpg.android.habitica.events.TaskTappedEvent;
import com.habitrpg.android.habitica.events.TodoCheckedEvent;
import com.habitrpg.android.habitica.events.ToggledInnStateEvent;
import com.habitrpg.android.habitica.prefs.PrefsActivity;
import com.habitrpg.android.habitica.ui.AvatarWithBarsViewModel;
import com.habitrpg.android.habitica.ui.EditTextDrawer;
@ -198,9 +199,12 @@ public class MainActivity extends InstabugAppCompatActivity implements HabitRPGU
protected void onResume() {
super.onResume();
this.mAPIHelper = new APIHelper(this, hostConfig);
if(mAPIHelper == null)
{
this.mAPIHelper = new APIHelper(this, hostConfig);
mAPIHelper.retrieveUser(new HabitRPGUserCallback(this));
mAPIHelper.retrieveUser(new HabitRPGUserCallback(this));
}
}
@Override
@ -325,6 +329,12 @@ public class MainActivity extends InstabugAppCompatActivity implements HabitRPGU
}
}
public void onEvent(ToggledInnStateEvent event) {
User.getPreferences().setSleep(event.Inn);
updateUserAvatars();
}
private void notifyUser(double xp, double hp, double gold,
double lvl, double delta) {
StringBuilder message = new StringBuilder();
@ -471,24 +481,7 @@ public class MainActivity extends InstabugAppCompatActivity implements HabitRPGU
filterDrawer.openDrawer();
return true;
case R.id.action_toggle_sleep:
mAPIHelper.toggleSleep(new Callback<Void>() {
@Override
public void success(Void aVoid, Response response) {
}
@Override
public void failure(RetrofitError error) {
}
});
User.getPreferences().setSleep(!User.getPreferences().getSleep());
updateUserAvatars();
return true;
}
return super.onOptionsItemSelected(item);

View file

@ -1,22 +1,62 @@
package com.habitrpg.android.habitica;
import android.content.Context;
import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.support.design.widget.Snackbar;
import android.support.v4.app.Fragment;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.view.MenuItem;
import android.view.View;
import android.widget.LinearLayout;
import com.habitrpg.android.habitica.events.commands.CopyChatAsTodoCommand;
import com.habitrpg.android.habitica.events.commands.DeleteChatMessageCommand;
import com.habitrpg.android.habitica.events.commands.FlagChatMessageCommand;
import com.habitrpg.android.habitica.events.commands.OpenNewPMActivityCommand;
import com.habitrpg.android.habitica.events.commands.SendNewGroupMessageCommand;
import com.habitrpg.android.habitica.events.commands.ToggleInnCommand;
import com.habitrpg.android.habitica.events.ToggledInnStateEvent;
import com.habitrpg.android.habitica.prefs.PrefsActivity;
import com.habitrpg.android.habitica.ui.AvatarWithBarsViewModel;
import com.habitrpg.android.habitica.ui.MainDrawerBuilder;
import com.habitrpg.android.habitica.ui.adapter.TavernRecyclerViewAdapter;
import com.magicmicky.habitrpgwrapper.lib.models.ChatMessage;
import com.magicmicky.habitrpgwrapper.lib.models.HabitRPGUser;
import com.magicmicky.habitrpgwrapper.lib.models.PostChatMessageResult;
import com.mikepenz.materialdrawer.Drawer;
import com.raizlabs.android.dbflow.sql.builder.Condition;
import com.raizlabs.android.dbflow.sql.language.Select;
import java.util.List;
import butterknife.ButterKnife;
import butterknife.InjectView;
import de.greenrobot.event.EventBus;
import retrofit.Callback;
import retrofit.RetrofitError;
import retrofit.client.Response;
public class TavernActivity extends AppCompatActivity {
public class TavernActivity extends AppCompatActivity implements Callback<List<ChatMessage>> {
@InjectView(R.id.toolbar)
Toolbar toolbar;
@InjectView(R.id.avatar)
LinearLayout avatarHeader;
@InjectView(R.id.tavern_list)
RecyclerView recyclerView;
private AvatarWithBarsViewModel avatarInHeader;
private APIHelper mAPIHelper;
private HabitRPGUser User;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@ -26,17 +66,20 @@ public class TavernActivity extends AppCompatActivity {
setSupportActionBar(toolbar);
// Receive Events
EventBus.getDefault().register(this);
ActionBar actionBar = getSupportActionBar();
// Enable Backbutton
if (actionBar != null) {
actionBar.setTitle(R.string.about_title);
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setDisplayShowHomeEnabled(false);
actionBar.setDisplayShowTitleEnabled(true);
actionBar.setDisplayUseLogoEnabled(false);
actionBar.setHomeButtonEnabled(false);
actionBar.setElevation(0);
toolbar.setTitleTextColor(this.getResources().getColor(R.color.white));
}
Drawer drawer = MainDrawerBuilder.CreateDefaultBuilderSettings(this, toolbar)
@ -44,9 +87,100 @@ public class TavernActivity extends AppCompatActivity {
.withTranslucentStatusBar(false)
.withDisplayBelowStatusBar(false)
.withDisplayBelowToolbar(false)
.withActionBarDrawerToggle(false)
.withSelectedItem(2)
.build();
avatarInHeader = new AvatarWithBarsViewModel(this, avatarHeader);
HostConfig hostConfig = PrefsActivity.fromContext(this);
User = new Select().from(HabitRPGUser.class).where(Condition.column("id").eq(hostConfig.getUser())).querySingle();
avatarInHeader.UpdateData(User);
mAPIHelper = new APIHelper(this, hostConfig);
mAPIHelper.apiService.listGroupChat("habitrpg", this);
}
private void showSnackbar(String msg, boolean negative){
Snackbar snackbar = Snackbar.make(recyclerView, msg, Snackbar.LENGTH_LONG);
if (negative) {
View snackbarView = snackbar.getView();
//change Snackbar's background color;
snackbarView.setBackgroundColor(getResources().getColor(R.color.red));
}
snackbar.show();
}
public void onEvent(FlagChatMessageCommand cmd){
showSnackbar("Not yet implemented!", false);
}
public void onEvent(OpenNewPMActivityCommand cmd){
showSnackbar("Not yet implemented!", false);
}
public void onEvent(CopyChatAsTodoCommand cmd){
showSnackbar("Not yet implemented!", false);
}
public void onEvent(final DeleteChatMessageCommand cmd) {
mAPIHelper.apiService.deleteMessage(cmd.groupId, cmd.chatMessage.id, new Callback<Void>() {
@Override
public void success(Void aVoid, Response response) {
if (currentChatMessages != null) {
currentChatMessages.remove(cmd.chatMessage);
TavernActivity.this.success(currentChatMessages, null);
}
}
@Override
public void failure(RetrofitError error) {
}
});
}
public void onEvent(SendNewGroupMessageCommand cmd) {
mAPIHelper.apiService.postGroupChat(cmd.TargetGroupId, cmd.Message, new Callback<PostChatMessageResult>() {
@Override
public void success(PostChatMessageResult msg, Response response) {
if (currentChatMessages != null) {
currentChatMessages.add(0, msg.message);
TavernActivity.this.success(currentChatMessages, null);
}
}
@Override
public void failure(RetrofitError error) {
}
});
}
public void onEvent(ToggleInnCommand event) {
mAPIHelper.toggleSleep(new Callback<Void>() {
@Override
public void success(Void aVoid, Response response) {
ToggledInnStateEvent innState = new ToggledInnStateEvent();
innState.Inn = !User.getPreferences().getSleep();
User.getPreferences().setSleep(innState.Inn);
avatarInHeader.UpdateData(User);
EventBus.getDefault().post(innState);
}
@Override
public void failure(RetrofitError error) {
}
});
}
@Override
@ -65,4 +199,25 @@ public class TavernActivity extends AppCompatActivity {
return super.onOptionsItemSelected(item);
}
private List<ChatMessage> currentChatMessages;
@Override
public void success(List<ChatMessage> chatMessages, Response response) {
currentChatMessages = chatMessages;
TavernRecyclerViewAdapter tavernAdapter = new TavernRecyclerViewAdapter(chatMessages, this, User.getId());
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
//recyclerView.setHasFixedSize(true);
recyclerView.setAdapter(tavernAdapter);
}
@Override
public void failure(RetrofitError error) {
showSnackbar(error.getMessage(), true);
}
}

View file

@ -0,0 +1,8 @@
package com.habitrpg.android.habitica.events;
/**
* Created by Negue on 24.08.2015.
*/
public class ToggledInnStateEvent {
public boolean Inn;
}

View file

@ -0,0 +1,7 @@
package com.habitrpg.android.habitica.events.commands;
/**
* Created by Negue on 30.08.2015.
*/
public class CopyChatAsTodoCommand {
}

View file

@ -0,0 +1,16 @@
package com.habitrpg.android.habitica.events.commands;
import com.magicmicky.habitrpgwrapper.lib.models.ChatMessage;
/**
* Created by Negue on 30.08.2015.
*/
public class DeleteChatMessageCommand {
public String groupId;
public ChatMessage chatMessage;
public DeleteChatMessageCommand(String groupId, ChatMessage chatMessage){
this.groupId = groupId;
this.chatMessage = chatMessage;
}
}

View file

@ -0,0 +1,8 @@
package com.habitrpg.android.habitica.events.commands;
/**
* Created by Negue on 30.08.2015.
*/
public class FlagChatMessageCommand {
}

View file

@ -0,0 +1,7 @@
package com.habitrpg.android.habitica.events.commands;
/**
* Created by Negue on 30.08.2015.
*/
public class OpenNewPMActivityCommand {
}

View file

@ -0,0 +1,14 @@
package com.habitrpg.android.habitica.events.commands;
/**
* Created by Negue on 24.08.2015.
*/
public class SendNewGroupMessageCommand {
public String Message;
public String TargetGroupId;
public SendNewGroupMessageCommand(String targetGroupId, String message){
TargetGroupId = targetGroupId;
Message = message;
}
}

View file

@ -0,0 +1,7 @@
package com.habitrpg.android.habitica.events.commands;
/**
* Created by Negue on 24.08.2015.
*/
public class ToggleInnCommand {
}

View file

@ -123,6 +123,11 @@ public class AvatarWithBarsViewModel {
}
}
@BindingAdapter("app:rounded_background_int")
public static void setRoundedBackgroundInt(View view, int color) {
setRoundedBackground(view, view.getResources().getColor(color));
}
public static class LayoutWeightAnimation extends Animation {
float targetWeight;
float initializeWeight;

View file

@ -17,6 +17,7 @@ import android.widget.CheckBox;
import android.widget.CheckedTextView;
import android.widget.CompoundButton;
import android.widget.ImageView;
import android.widget.TextView;
import com.habitrpg.android.habitica.R;
import com.habitrpg.android.habitica.databinding.DailyItemCardBinding;
@ -197,6 +198,8 @@ public class HabitItemRecyclerViewAdapter<THabitItem extends Task>
handler.postDelayed(reloadContentRunable, 200);
}
// TODO Move them to a separate class
@BindingAdapter("bind:imageName")
public static void loadImage(ImageView view, String imageName) {
Picasso.with(view.getContext()).load("https://habitica-assets.s3.amazonaws.com/mobileApp/images/shop_"+ imageName +".png").into(view);
@ -222,6 +225,11 @@ public class HabitItemRecyclerViewAdapter<THabitItem extends Task>
view.setBackgroundColor(view.getResources().getColor(color));
}
@BindingAdapter("app:foregroundColor")
public static void setForegroundTintColor(TextView view, int color) {
view.setTextColor(view.getResources().getColor(color));
}
public abstract class ViewHolder<THabitItem extends Task> extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener {
protected android.content.res.Resources resources;

View file

@ -0,0 +1,261 @@
package com.habitrpg.android.habitica.ui.adapter;
import android.content.Context;
import android.databinding.DataBindingUtil;
import android.support.v7.widget.AppCompatEditText;
import android.support.v7.widget.PopupMenu;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import com.habitrpg.android.habitica.R;
import com.habitrpg.android.habitica.databinding.TavernChatItemBinding;
import com.habitrpg.android.habitica.events.commands.CopyChatAsTodoCommand;
import com.habitrpg.android.habitica.events.commands.DeleteChatMessageCommand;
import com.habitrpg.android.habitica.events.commands.FlagChatMessageCommand;
import com.habitrpg.android.habitica.events.commands.OpenNewPMActivityCommand;
import com.habitrpg.android.habitica.events.commands.SendNewGroupMessageCommand;
import com.habitrpg.android.habitica.events.commands.ToggleInnCommand;
import com.habitrpg.android.habitica.ui.helpers.ViewHelper;
import com.magicmicky.habitrpgwrapper.lib.models.ChatMessage;
import com.mikepenz.iconics.Iconics;
import com.mikepenz.iconics.typeface.FontAwesome;
import java.lang.reflect.Field;
import java.util.List;
import butterknife.ButterKnife;
import butterknife.InjectView;
import butterknife.Optional;
import de.greenrobot.event.EventBus;
/**
* Created by Negue on 20.08.2015.
*/
public class TavernRecyclerViewAdapter extends RecyclerView.Adapter<TavernRecyclerViewAdapter.TavernRecyclerViewHolder> {
static final int TYPE_DANIEL = 0;
static final int TYPE_NEW_MESSAGE = 1;
static final int TYPE_MESSAGE = 2;
private List<ChatMessage> messages;
private Context viewContext;
private String uuid;
public TavernRecyclerViewAdapter(List<ChatMessage> messages, Context viewContext, String uuid) {
this.messages = messages;
this.viewContext = viewContext;
this.uuid = uuid;
}
@Override
public int getItemViewType(int position) {
switch (position) {
case 0: {
return TYPE_DANIEL;
}
case 1: {
return TYPE_NEW_MESSAGE;
}
default: {
return TYPE_MESSAGE;
}
}
}
@Override
public TavernRecyclerViewHolder 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;
}
}
View view = LayoutInflater.from(parent.getContext())
.inflate(rLayout, parent, false);
return new TavernRecyclerViewHolder(view, viewType, viewContext, uuid);
}
@Override
public void onBindViewHolder(TavernRecyclerViewHolder holder, int position) {
if (position > 1) {
holder.bind(messages.get(position - 2));
}
}
@Override
public int getItemCount() {
return messages.size() + 2;
}
public class TavernRecyclerViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, PopupMenu.OnMenuItemClickListener {
private int layoutType;
private String uuid;
private TavernChatItemBinding chatItemBinding;
// Toggle Inn State
@InjectView(R.id.btn_toggle_inn)
@Optional
Button btnToggleInn;
// New Msg
@InjectView(R.id.edit_new_message_text)
@Optional
AppCompatEditText textNewMessage;
@InjectView(R.id.btn_send_message)
@Optional
Button btnSendNewMessage;
Context context;
public TavernRecyclerViewHolder(View itemView, int layoutType, Context viewContext, String uuid) {
super(itemView);
this.layoutType = layoutType;
this.uuid = uuid;
ButterKnife.inject(this, itemView);
context = viewContext;
switch (layoutType) {
case TYPE_DANIEL: {
btnToggleInn.setOnClickListener(this);
ViewHelper.SetBackgroundTint(btnToggleInn, itemView.getResources().getColor(R.color.brand));
break;
}
case TYPE_NEW_MESSAGE: {
btnSendNewMessage.setOnClickListener(this);
int color = itemView.getResources().getColor(R.color.brand);
// Using the Iconics buttons, it is unable to tint the background
btnSendNewMessage.setTypeface(Iconics.findFont(FontAwesome.Icon.faw_comment).getTypeface(context));
btnSendNewMessage.setText(new Iconics.IconicsBuilder().ctx(context).on("{faw-comment}").build());
ViewHelper.SetBackgroundTint(btnSendNewMessage, color);
break;
}
default: {
chatItemBinding = DataBindingUtil.bind(itemView);
chatItemBinding.btnOptions.setClickable(true);
chatItemBinding.btnOptions.setOnClickListener(this);
}
}
}
public void bind(ChatMessage msg) {
if (layoutType != TYPE_DANIEL && layoutType != TYPE_NEW_MESSAGE) {
chatItemBinding.setMsg(msg);
}
}
@Override
public void onClick(View v) {
if (chatItemBinding != null && chatItemBinding.btnOptions == v) {
PopupMenu popupMenu = new PopupMenu(context, v);
//set my own listener giving the View that activates the event onClick (i.e. YOUR ImageView)
popupMenu.setOnMenuItemClickListener(this);
//inflate your PopUpMenu
popupMenu.getMenuInflater().inflate(R.menu.chat_message, popupMenu.getMenu());
// Force icons to show
Object menuHelper = null;
Class[] argTypes;
try {
Field fMenuHelper = PopupMenu.class.getDeclaredField("mPopup");
fMenuHelper.setAccessible(true);
menuHelper = fMenuHelper.get(popupMenu);
argTypes = new Class[]{boolean.class};
menuHelper.getClass().getDeclaredMethod("setForceShowIcon", argTypes).invoke(menuHelper, true);
} catch (Exception e) {
}
ChatMessage chatMsg = chatItemBinding.getMsg();
if (!chatMsg.uuid.equals(uuid)) {
popupMenu.getMenu().findItem(R.id.menu_chat_delete).setVisible(false);
}
popupMenu.show();
// Try to force some horizontal offset
try {
Field fListPopup = menuHelper.getClass().getDeclaredField("mPopup");
fListPopup.setAccessible(true);
Object listPopup = fListPopup.get(menuHelper);
argTypes = new Class[]{int.class};
Class listPopupClass = listPopup.getClass();
// Get the width of the popup window
int width = (Integer) listPopupClass.getDeclaredMethod("getWidth").invoke(listPopup);
// Invoke setHorizontalOffset() with the negative width to move left by that distance
listPopupClass.getDeclaredMethod("setHorizontalOffset", argTypes).invoke(listPopup, -width);
// Invoke show() to update the window's position
listPopupClass.getDeclaredMethod("show").invoke(listPopup);
} catch (Exception e) {
}
} else if (v == btnToggleInn) {
EventBus.getDefault().post(new ToggleInnCommand());
} else {
String text = textNewMessage.getText().toString();
EventBus.getDefault().post(new SendNewGroupMessageCommand("habitrpg", text));
textNewMessage.setText("");
}
}
@Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_chat_delete: {
EventBus.getDefault().post(new DeleteChatMessageCommand("habitrpg", chatItemBinding.getMsg()));
break;
}
case R.id.menu_chat_flag: {
EventBus.getDefault().post(new FlagChatMessageCommand());
break;
}
case R.id.menu_chat_copy_as_todo: {
EventBus.getDefault().post(new CopyChatAsTodoCommand());
break;
}
case R.id.menu_chat_send_pm: {
EventBus.getDefault().post(new OpenNewPMActivityCommand());
break;
}
}
return false;
}
}
}

View file

@ -1,7 +1,9 @@
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.HabitRPGUser;
import com.magicmicky.habitrpgwrapper.lib.models.PostChatMessageResult;
import com.magicmicky.habitrpgwrapper.lib.models.Status;
import com.magicmicky.habitrpgwrapper.lib.models.Tag;
import com.magicmicky.habitrpgwrapper.lib.models.TaskDirectionData;
@ -9,6 +11,7 @@ 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.List;
@ -19,6 +22,7 @@ import retrofit.http.GET;
import retrofit.http.POST;
import retrofit.http.PUT;
import retrofit.http.Path;
import retrofit.http.Query;
/**
* Created by MagicMicky on 10/06/2014.
@ -81,6 +85,15 @@ public interface ApiService {
@POST("/user/sleep")
void sleep(Callback<Void> voidCallback);
@GET("/groups/{gid}/chat")
void listGroupChat(@Path("gid") String groupId, Callback<List<ChatMessage>> cb);
@POST("/groups/{gid}/chat")
void postGroupChat(@Path("gid") String groupId, @Query("message") String message, Callback<PostChatMessageResult> cb);
@DELETE("/groups/{gid}/chat/{messageId}")
void deleteMessage(@Path("gid") String groupId, @Path("messageId") String messageId, Callback<Void> cb);
/*
@GET("/content")
void getContent();//Check Callback

View file

@ -0,0 +1,91 @@
package com.magicmicky.habitrpgwrapper.lib.models;
import com.habitrpg.android.habitica.R;
import java.util.Date;
import java.util.Dictionary;
import java.util.HashMap;
/**
* Created by Negue on 22.08.2015.
*/
public class ChatMessage {
static HashMap<Integer, Integer> contributorColorDict;
static {
contributorColorDict = new HashMap<>();
contributorColorDict.put(0, R.color.contributor_0);
contributorColorDict.put(1, R.color.contributor_1);
contributorColorDict.put(2, R.color.contributor_2);
contributorColorDict.put(3, R.color.contributor_3);
contributorColorDict.put(4, R.color.contributor_4);
contributorColorDict.put(5, R.color.contributor_5);
contributorColorDict.put(6, R.color.contributor_6);
contributorColorDict.put(7, R.color.contributor_7);
contributorColorDict.put(8, R.color.contributor_mod);
}
public String id;
public String text;
public long timestamp;
// TODO LIKES
// TODO Flags
public String uuid;
public Contributor contributor;
public String user;
public int getContributorColor() {
int rColor = android.R.color.black;
if (contributor != null) {
if (contributor.admin) {
rColor = R.color.contributor_staff;
} else {
if (contributorColorDict.containsKey(contributor.level))
rColor = contributorColorDict.get(contributor.level);
}
}
return rColor;
}
public int getContributorForegroundColor() {
int rColor = android.R.color.white;
if (contributor != null && contributor.level == 8) {
rColor = R.color.contributor_npc_font;
}
return rColor;
}
public String getAgoString() {
long diff = new Date().getTime() - timestamp;
long diffMinutes = diff / (60 * 1000) % 60;
long diffHours = diff / (60 * 60 * 1000) % 24;
long diffDays = diff / (24 * 60 * 60 * 1000);
if (diffDays != 0) {
return diffDays + " days ago";
}
if (diffHours != 0) {
return diffHours + " hours ago";
}
return diffMinutes + " minutes ago";
}
}

View file

@ -0,0 +1,11 @@
package com.magicmicky.habitrpgwrapper.lib.models;
public class Contributor {
public boolean admin;
public String contributions;
public int level;
public String text;
}

View file

@ -0,0 +1,8 @@
package com.magicmicky.habitrpgwrapper.lib.models;
/**
* Created by Negue on 30.08.2015.
*/
public class PostChatMessageResult {
public ChatMessage message;
}

View file

@ -8,7 +8,7 @@ buildscript {
}
dependencies {
classpath 'com.android.tools.build:gradle:1.3.0-beta1'
classpath 'com.android.tools.build:gradle:1.3.0'
classpath 'com.android.databinding:dataBinder:1.0-rc1'
//Class path for the plugin to auto download sources