Merge pull request #572 from TheHollidayInn/social-notifications

Social notifications
This commit is contained in:
Phillip Thelen 2016-08-04 19:25:36 +02:00 committed by GitHub
commit 914b585d71
37 changed files with 1346 additions and 53 deletions

1
.gitignore vendored
View file

@ -54,3 +54,4 @@ fabric.properties
Habitica/res/values/secret_strings.xml
habitica.properties
habitica.resources
Habitica/google-services.json

View file

@ -41,5 +41,6 @@ android:
script:
- cp habitica.properties.travis habitica.properties
- cp habitica.resources.example habitica.resources
- cp Habitica/google-services.json.example Habitica/google-services.json
- ./gradlew assembleDebug
- ./gradlew testDebugUnitTest --info

View file

@ -122,12 +122,35 @@
<receiver android:process=":remote" android:name=".NotificationPublisher" />
<receiver android:process=":remote" android:name=".receivers.TaskReceiver"></receiver>
<receiver android:name=".receivers.LocalNotificationActionReceiver">
<intent-filter>
<action android:name="@string/accept_party_invite"/>
<action android:name="@string/reject_party_invite"/>
<action android:name="@string/accept_quest_invite"/>
<action android:name="@string/reject_quest_invite"/>
</intent-filter>
</receiver>
<receiver android:name=".receivers.TaskAlarmBootReceiver" android:permission="android.permission.RECEIVE_BOOT_COMPLETED">
<intent-filter>
<action android:name="android.intent.action._BOOT_COMPLETED"/>
</intent-filter>
</receiver>
<service
android:name=".helpers.notifications.HabiticaFirebaseMessagingService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT"/>
</intent-filter>
</service>
<service
android:name=".helpers.notifications.HabiticaFirebaseInstanceIDService">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
</intent-filter>
</service>
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.habitrpg.android.habitica.fileprovider"

View file

@ -140,6 +140,10 @@ dependencies {
//Leak Detection
debugCompile 'com.squareup.leakcanary:leakcanary-android:1.3.1'
releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.3.1'
//Push Notifications
compile 'com.google.firebase:firebase-core:9.0.2'
compile 'com.google.firebase:firebase-messaging:9.0.2'
}
android {
@ -276,3 +280,4 @@ apply plugin: 'com.getkeepsafe.dexcount'
apply plugin: 'com.android.application' //or apply plugin: 'java'
apply plugin: 'me.tatarka.retrolambda'
apply plugin: 'com.jakewharton.hugo'
apply plugin: 'com.google.gms.google-services'

View file

@ -0,0 +1,73 @@
{
"project_info": {
"project_number": "project-number",
"firebase_url": "https://example.firebaseio.com",
"project_id": "project-id",
"storage_bucket": "storage.bucket"
},
"client": [
{
"client_info": {
"mobilesdk_app_id": "app-id",
"android_client_info": {
"package_name": "com.habitrpg.android.habitica.debug"
}
},
"oauth_client": [
{
"client_id": "client-key",
"client_type": 3
}
],
"api_key": [
{
"current_key": "api-key"
}
],
"services": {
"analytics_service": {
"status": 1
},
"appinvite_service": {
"status": 1,
"other_platform_oauth_client": []
},
"ads_service": {
"status": 2
}
}
},
{
"client_info": {
"mobilesdk_app_id": "app-id",
"android_client_info": {
"package_name": "com.habitrpg.android.habitica.debug"
}
},
"oauth_client": [
{
"client_id": "client-id",
"client_type": 3
}
],
"api_key": [
{
"current_key": "api-key"
}
],
"services": {
"analytics_service": {
"status": 1
},
"appinvite_service": {
"status": 1,
"other_platform_oauth_client": []
},
"ads_service": {
"status": 2
}
}
}
],
"configuration_version": "1"
}

View file

@ -7,4 +7,12 @@
<string name="SP_username" translatable="false">Username</string>
<string name="SP_email" translatable="false">E-mail</string>
<string name="base_url" translatable="false">https://habitica.com</string>
<!-- Local notification actions -->
<string name="accept_party_invite" translatable="false">ACCEPT_PARTY_INVITE</string>
<string name="reject_party_invite" translatable="false">REJECT_PARTY_INVITE</string>
<string name="accept_guild_invite" translatable="false">ACCEPT_GUILD_INVITE</string>
<string name="reject_guild_invite" translatable="false">REJECT_GUILD_INVITE</string>
<string name="accept_quest_invite" translatable="false">ACCEPT_QUEST_INVITE</string>
<string name="reject_quest_invite" translatable="false">REJECT_QUEST_INVITE</string>
</resources>

View file

@ -22,6 +22,17 @@
<string name="pref_reminder_checkbox">Activate Reminder</string>
<string name="pref_reminder_picker">Set Reminder Time</string>
<string name="pref_push_notifications_checkbox">User Push Notifications</string>
<string name="push_notifications">Push Notifications</string>
<string name="preference_push_you_won_challenge">You won a Challenge!</string>
<string name="preference_push_received_a_private_message">Received a Private Message</string>
<string name="preference_push_gifted_gems">Gifted Gems</string>
<string name="preference_push_gifted_subscription">Gifted Subscription</string>
<string name="preference_push_invited_to_party">Invited to Party</string>
<string name="preference_push_invited_to_guild">Invited to Guiild</string>
<string name="preference_push_your_quest_has_begun">Your Quest has Begun</string>
<string name="preference_push_invited_to_quest">Invited to Quest</string>
<!-- Adding tasks -->
<string name="task_value">Value</string>
<string name="new_todo">New todo</string>

View file

@ -75,4 +75,67 @@
</PreferenceCategory>
<PreferenceCategory
android:title="@string/push_notifications">
<CheckBoxPreference
android:key="usePushNotifications"
android:defaultValue="true"
android:title="@string/pref_push_notifications_checkbox"/>
<PreferenceScreen
android:key="pushNotifications"
android:title="@string/push_notifications"
android:summary="Set your push notifications settings"
android:order="1">
<PreferenceCategory android:title="Push Notifications">
<CheckBoxPreference
android:key="preference_push_you_won_challenge"
android:defaultValue="true"
android:title="@string/preference_push_you_won_challenge"/>
<CheckBoxPreference
android:key="preference_push_received_a_private_message"
android:defaultValue="true"
android:title="@string/preference_push_received_a_private_message"/>
<CheckBoxPreference
android:key="preference_push_gifted_gems"
android:defaultValue="true"
android:title="@string/preference_push_gifted_gems"/>
<CheckBoxPreference
android:key="preference_push_gifted_subscription"
android:defaultValue="true"
android:title="@string/preference_push_gifted_subscription"/>
<CheckBoxPreference
android:key="preference_push_invited_to_party"
android:defaultValue="true"
android:title="@string/preference_push_invited_to_party"/>
<CheckBoxPreference
android:key="preference_push_invited_to_guild"
android:defaultValue="true"
android:title="@string/preference_push_invited_to_guild"/>
<CheckBoxPreference
android:key="preference_push_your_quest_has_begun"
android:defaultValue="true"
android:title="@string/preference_push_your_quest_has_begun"/>
<CheckBoxPreference
android:key="preference_push_invited_to_quest"
android:defaultValue="true"
android:title="@string/preference_push_invited_to_quest"/>
</PreferenceCategory>
</PreferenceScreen>
</PreferenceCategory>
</PreferenceScreen>

View file

@ -7,5 +7,5 @@ public class HabitDatabase {
public static final String NAME = "Habitica";
public static final int VERSION = 23;
public static final int VERSION = 24;
}

View file

@ -1,8 +1,10 @@
package com.habitrpg.android.habitica.components;
import com.habitrpg.android.habitica.HabiticaApplication;
import com.habitrpg.android.habitica.helpers.notifications.PushNotificationManager;
import com.habitrpg.android.habitica.modules.ApiModule;
import com.habitrpg.android.habitica.modules.AppModule;
import com.habitrpg.android.habitica.receivers.LocalNotificationActionReceiver;
import com.habitrpg.android.habitica.ui.activities.AboutActivity;
import com.habitrpg.android.habitica.ui.activities.ClassSelectionActivity;
import com.habitrpg.android.habitica.ui.activities.GroupFormActivity;
@ -156,4 +158,8 @@ public interface AppComponent {
void inject(ShopsFragment shopsFragment);
void inject(ShopFragment shopFragment);
void inject(PushNotificationManager pushNotificationManager);
void inject(LocalNotificationActionReceiver localNotificationActionReceiver);
}

View file

@ -0,0 +1,56 @@
package com.habitrpg.android.habitica.helpers.notifications;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.NotificationCompat;
import com.habitrpg.android.habitica.R;
import com.habitrpg.android.habitica.receivers.LocalNotificationActionReceiver;
import java.util.Map;
/**
* Created by keithholliday on 7/1/16.
*/
public class GuildInviteLocalNotification extends HabiticaLocalNotification {
@Override
public void notifyLocally(Context context, String title, String message) {
super.notifyLocally(context, title, message);
this.setNotificationActions();
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(10, notificationBuilder.build());
}
protected void setNotificationActions() {
Resources res = context.getResources();
Intent acceptInviteIntent = new Intent(context, LocalNotificationActionReceiver.class);
acceptInviteIntent.setAction(res.getString(R.string.accept_guild_invite));
acceptInviteIntent.putExtra("groupID", this.data.get("groupID"));
PendingIntent pendingIntentAccept = PendingIntent.getBroadcast(
context,
3000,
acceptInviteIntent,
PendingIntent.FLAG_UPDATE_CURRENT
);
notificationBuilder.addAction(0, "Accept", pendingIntentAccept);
Intent rejectInviteIntent = new Intent(context, LocalNotificationActionReceiver.class);
rejectInviteIntent.setAction(res.getString(R.string.reject_guild_invite));
rejectInviteIntent.putExtra("groupID", this.data.get("groupID"));
PendingIntent pendingIntentReject = PendingIntent.getBroadcast(
context,
2000,
rejectInviteIntent,
PendingIntent.FLAG_UPDATE_CURRENT
);
notificationBuilder.addAction(0, "Reject", pendingIntentReject);
}
}

View file

@ -0,0 +1,28 @@
package com.habitrpg.android.habitica.helpers.notifications;
import android.util.Log;
import com.google.firebase.iid.FirebaseInstanceId;
import com.google.firebase.iid.FirebaseInstanceIdService;
import com.habitrpg.android.habitica.APIHelper;
import java.util.HashMap;
import java.util.Map;
import javax.inject.Inject;
/**
* Created by keithholliday on 6/24/16.
*/
public class HabiticaFirebaseInstanceIDService extends FirebaseInstanceIdService {
public PushNotificationManager pushNotificationManager;
@Override
public void onTokenRefresh() {
pushNotificationManager = PushNotificationManager.getInstance(this);
String refreshedToken = FirebaseInstanceId.getInstance().getToken();
pushNotificationManager.setRefreshedToken(refreshedToken);
}
}

View file

@ -0,0 +1,17 @@
package com.habitrpg.android.habitica.helpers.notifications;
import android.util.Log;
import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;
/**
* Created by keithholliday on 6/24/16.
*/
public class HabiticaFirebaseMessagingService extends FirebaseMessagingService {
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
PushNotificationManager pushNotificationManager = PushNotificationManager.getInstance(this);
pushNotificationManager.displayNotification(remoteMessage);
}
}

View file

@ -0,0 +1,47 @@
package com.habitrpg.android.habitica.helpers.notifications;
import android.content.Context;
import android.media.RingtoneManager;
import android.net.Uri;
import android.support.annotation.CallSuper;
import android.support.v4.app.NotificationCompat;
import com.habitrpg.android.habitica.R;
import java.util.Map;
/**
* Created by keithholliday on 6/28/16.
*/
public abstract class HabiticaLocalNotification {
protected Map<String, String> data;
protected Context context;
protected String title;
protected String message;
protected NotificationCompat.Builder notificationBuilder;
@CallSuper
public void notifyLocally(Context context, String title, String message) {
this.context = context;
this.title = title;
this.message = message;
Uri path = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
this.notificationBuilder =
new NotificationCompat.Builder(context)
.setSmallIcon(R.drawable.ic_gryphon)
.setContentTitle(title)
.setContentText(message)
.setAutoCancel(true)
.setSound(path);
}
public void setExtras(Map<String, String> data) {
this.data = data;
}
protected abstract void setNotificationActions();
}

View file

@ -0,0 +1,35 @@
package com.habitrpg.android.habitica.helpers.notifications;
/**
* Created by keithholliday on 6/28/16.
*/
public class HabiticaLocalNotificationFactory {
//use getShape method to get object of type shape
public HabiticaLocalNotification build(String notificationType){
if(notificationType == null){
return null;
}
if (notificationType.equalsIgnoreCase(PushNotificationManager.PARTY_INVITE_PUSH_NOTIFICATION_KEY)) {
return new PartyInviteLocalNotification();
} else if (notificationType.contains(PushNotificationManager.RECEIVED_PRIVATE_MESSAGE_PUSH_NOTIFICATION_KEY)) {
return new ReceivedPrivateMessageLocalNotification();
} else if (notificationType.contains(PushNotificationManager.RECEIVED_GEMS_PUSH_NOTIFICATION_KEY)) {
return new ReceivedGemsGiftLocalNotification();
} else if (notificationType.contains(PushNotificationManager.RECEIVED_SUBSCRIPTION_GIFT_PUSH_NOTIFICATION_KEY)) {
return new ReceivedSubscriptionGiftLocalNotification();
} else if (notificationType.contains(PushNotificationManager.GUILD_INVITE_PUSH_NOTIFICATION_KEY)) {
return new GuildInviteLocalNotification();
} else if (notificationType.contains(PushNotificationManager.QUEST_INVITE_PUSH_NOTIFICATION_KEY)) {
return new QuestInviteLocalNotification();
} else if (notificationType.contains(PushNotificationManager.QUEST_BEGUN_PUSH_NOTIFICATION_KEY)) {
return new QuestBegunLocalNotification();
} else if (notificationType.contains(PushNotificationManager.WON_CHALLENGE_PUSH_NOTIFICATION_KEY)) {
return new WonChallengeLocalNotification();
}
return null;
}
}

View file

@ -0,0 +1,56 @@
package com.habitrpg.android.habitica.helpers.notifications;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.media.RingtoneManager;
import android.net.Uri;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
import com.habitrpg.android.habitica.R;
import com.habitrpg.android.habitica.receivers.LocalNotificationActionReceiver;
import com.habitrpg.android.habitica.ui.activities.MainActivity;
import java.util.Map;
/**
* Created by keithholliday on 6/28/16.
*/
public class PartyInviteLocalNotification extends HabiticaLocalNotification {
public void notifyLocally(Context context, String title, String message) {
super.notifyLocally(context, title, message);
this.setNotificationActions();
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(10, notificationBuilder.build());
}
protected void setNotificationActions() {
Resources res = context.getResources();
Intent acceptInviteIntent = new Intent(context, LocalNotificationActionReceiver.class);
acceptInviteIntent.setAction(res.getString(R.string.accept_party_invite));
PendingIntent pendingIntentAccept = PendingIntent.getBroadcast(
context,
3000,
acceptInviteIntent,
PendingIntent.FLAG_UPDATE_CURRENT
);
notificationBuilder.addAction(0, "Accept", pendingIntentAccept);
Intent rejectInviteIntent = new Intent(context, LocalNotificationActionReceiver.class);
rejectInviteIntent.setAction(res.getString(R.string.reject_party_invite));
PendingIntent pendingIntentReject = PendingIntent.getBroadcast(
context,
2000,
rejectInviteIntent,
PendingIntent.FLAG_UPDATE_CURRENT
);
notificationBuilder.addAction(0, "Reject", pendingIntentReject);
}
}

View file

@ -0,0 +1,159 @@
package com.habitrpg.android.habitica.helpers.notifications;
import android.content.Context;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.util.Log;
import com.google.firebase.iid.FirebaseInstanceId;
import com.google.firebase.messaging.RemoteMessage;
import com.habitrpg.android.habitica.APIHelper;
import com.habitrpg.android.habitica.HabiticaApplication;
import com.habitrpg.android.habitica.callbacks.HabitRPGUserCallback;
import com.magicmicky.habitrpgwrapper.lib.models.HabitRPGUser;
import com.magicmicky.habitrpgwrapper.lib.models.PushDevice;
import java.util.HashMap;
import java.util.Map;
import javax.inject.Inject;
/**
* Created by keithholliday on 6/27/16.
*/
public class PushNotificationManager {
private static PushNotificationManager instance = null;
public static String DEVICE_TOKEN_PREFERENCE_KEY = "device-token-preference";
public static String PARTY_INVITE_PUSH_NOTIFICATION_KEY = "invitedParty";
public static String RECEIVED_PRIVATE_MESSAGE_PUSH_NOTIFICATION_KEY = "newPM";
public static String RECEIVED_GEMS_PUSH_NOTIFICATION_KEY = "giftedGems";
public static String RECEIVED_SUBSCRIPTION_GIFT_PUSH_NOTIFICATION_KEY = "giftedSubscription";
public static String GUILD_INVITE_PUSH_NOTIFICATION_KEY = "invitedGuild";
public static String QUEST_INVITE_PUSH_NOTIFICATION_KEY = "questInvitation";
public static String QUEST_BEGUN_PUSH_NOTIFICATION_KEY = "questStarted";
public static String WON_CHALLENGE_PUSH_NOTIFICATION_KEY = "wonChallenge";
@Inject
public APIHelper apiHelper;
private String refreshedToken;
private SharedPreferences sharedPreferences;
private Context context;
private HabitRPGUser user;
protected PushNotificationManager(Context context) {
HabiticaApplication.getInstance(context).getComponent().inject(this);
sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
}
public void setUser(HabitRPGUser user) {
this.user = user;
}
public static PushNotificationManager getInstance(Context context) {
if(instance == null) {
instance = new PushNotificationManager(context);
}
instance.refreshedToken = instance.sharedPreferences.getString(DEVICE_TOKEN_PREFERENCE_KEY, "");
instance.context = context;
return instance;
}
public void setRefreshedToken (String refreshedToken) {
if (this.refreshedToken == null) {
return;
}
this.refreshedToken = refreshedToken;
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString(DEVICE_TOKEN_PREFERENCE_KEY, refreshedToken);
editor.commit();
}
//@TODO: Use preferences
public void addPushDeviceUsingStoredToken () {
if (this.refreshedToken == null || this.refreshedToken.isEmpty()) {
this.refreshedToken = FirebaseInstanceId.getInstance().getToken();
}
if (this.refreshedToken == null || this.refreshedToken.isEmpty()) {
return;
}
if (this.user == null || this.userHasPushDevice()) {
return;
}
if (!this.userIsSubscribedToNotifications()) {
return;
}
Map<String, String> pushDeviceData = new HashMap<String, String>();
pushDeviceData.put("regId", this.refreshedToken);
pushDeviceData.put("type", "android");
apiHelper.apiService.addPushDevice(pushDeviceData)
.compose(apiHelper.configureApiCallObserver())
.subscribe(aVoid -> {}, throwable -> {});
}
public void removePushDeviceUsingStoredToken () {
apiHelper.apiService.deletePushDevice(this.refreshedToken)
.compose(apiHelper.configureApiCallObserver())
.subscribe(aVoid -> {}, throwable -> {});
}
private Boolean userHasPushDevice() {
for(PushDevice pushDevice : this.user.getPushDevices()) {
if(pushDevice.getRegId().equals(this.refreshedToken)) {
return true;
}
}
return false;
}
public void displayNotification (RemoteMessage remoteMessage) {
String remoteMessageIdentifier = remoteMessage.getData().get("identifier");
HabiticaLocalNotificationFactory notificationFactory = new HabiticaLocalNotificationFactory();
HabiticaLocalNotification notification = notificationFactory.build(remoteMessageIdentifier);
if (userIsSubscribedToNotificationType(remoteMessageIdentifier) && notification != null) {
notification.setExtras(remoteMessage.getData());
notification.notifyLocally(this.context, remoteMessage.getData().get("title"), remoteMessage.getData().get("body"));
}
}
private boolean userIsSubscribedToNotifications() {
return sharedPreferences.getBoolean("pushNotifications", true);
}
private boolean userIsSubscribedToNotificationType(String type) {
String key = "";
//@TODO: If user has push turned off to send
if (type.equals(PARTY_INVITE_PUSH_NOTIFICATION_KEY)) {
key = "preference_push_invited_to_party";
} else if (type.contains(RECEIVED_PRIVATE_MESSAGE_PUSH_NOTIFICATION_KEY)) {
key = "preference_push_received_a_private_message";
} else if (type.contains(RECEIVED_GEMS_PUSH_NOTIFICATION_KEY)) {
key = "preference_push_gifted_gems";
} else if (type.contains(RECEIVED_SUBSCRIPTION_GIFT_PUSH_NOTIFICATION_KEY)) {
key = "preference_push_gifted_subscription";
} else if (type.contains(GUILD_INVITE_PUSH_NOTIFICATION_KEY)) {
key = "preference_push_invited_to_guild";
} else if (type.contains(QUEST_INVITE_PUSH_NOTIFICATION_KEY)) {
key = "preference_push_invited_to_quest";
} else if (type.contains(QUEST_BEGUN_PUSH_NOTIFICATION_KEY)) {
key = "preference_push_your_quest_has_begun";
} else if (type.contains(WON_CHALLENGE_PUSH_NOTIFICATION_KEY)) {
key = "preference_push_you_won_challenge";
}
return sharedPreferences.getBoolean(key, true);
}
}

View file

@ -0,0 +1,38 @@
package com.habitrpg.android.habitica.helpers.notifications;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.media.RingtoneManager;
import android.net.Uri;
import android.support.v4.app.NotificationCompat;
import com.habitrpg.android.habitica.R;
import com.habitrpg.android.habitica.ui.activities.MainActivity;
import java.util.Map;
/**
* Created by keithholliday on 7/1/16.
*/
public class QuestBegunLocalNotification extends HabiticaLocalNotification {
@Override
public void notifyLocally(Context context, String title, String message) {
super.notifyLocally(context, title, message);
this.setNotificationActions();
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(10000, notificationBuilder.build());
}
protected void setNotificationActions() {
Intent intent = new Intent(context, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(
context,
3000,
intent,
PendingIntent.FLAG_UPDATE_CURRENT
);
notificationBuilder.setContentIntent(pendingIntent);
}
}

View file

@ -0,0 +1,52 @@
package com.habitrpg.android.habitica.helpers.notifications;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.media.RingtoneManager;
import android.net.Uri;
import android.support.v4.app.NotificationCompat;
import com.habitrpg.android.habitica.R;
import com.habitrpg.android.habitica.receivers.LocalNotificationActionReceiver;
import java.util.Map;
/**
* Created by keithholliday on 7/1/16.
*/
public class QuestInviteLocalNotification extends HabiticaLocalNotification {
@Override
public void notifyLocally(Context context, String title, String message) {
super.notifyLocally(context, title, message);
this.setNotificationActions();
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(10000, notificationBuilder.build());
}
protected void setNotificationActions() {
Resources res = context.getResources();
Intent acceptInviteIntent = new Intent(context, LocalNotificationActionReceiver.class);
acceptInviteIntent.setAction(res.getString(R.string.accept_quest_invite));
PendingIntent pendingIntentAccept = PendingIntent.getBroadcast(
context,
3000,
acceptInviteIntent,
PendingIntent.FLAG_UPDATE_CURRENT
);
notificationBuilder.addAction(0, "Accept", pendingIntentAccept);
Intent rejectInviteIntent = new Intent(context, LocalNotificationActionReceiver.class);
rejectInviteIntent.setAction(res.getString(R.string.reject_quest_invite));
PendingIntent pendingIntentReject = PendingIntent.getBroadcast(
context,
2000,
rejectInviteIntent,
PendingIntent.FLAG_UPDATE_CURRENT
);
notificationBuilder.addAction(0, "Reject", pendingIntentReject);
}
}

View file

@ -0,0 +1,40 @@
package com.habitrpg.android.habitica.helpers.notifications;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.media.RingtoneManager;
import android.net.Uri;
import android.support.v4.app.NotificationCompat;
import com.habitrpg.android.habitica.R;
import com.habitrpg.android.habitica.receivers.LocalNotificationActionReceiver;
import com.habitrpg.android.habitica.ui.activities.MainActivity;
import java.util.Map;
/**
* Created by keithholliday on 7/1/16.
*/
public class ReceivedGemsGiftLocalNotification extends HabiticaLocalNotification {
@Override
public void notifyLocally(Context context, String title, String message) {
super.notifyLocally(context, title, message);
this.setNotificationActions();
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(10, notificationBuilder.build());
}
protected void setNotificationActions() {
Intent intent = new Intent(context, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(
context,
3000,
intent,
PendingIntent.FLAG_UPDATE_CURRENT
);
notificationBuilder.setContentIntent(pendingIntent);
}
}

View file

@ -0,0 +1,46 @@
package com.habitrpg.android.habitica.helpers.notifications;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.media.RingtoneManager;
import android.net.Uri;
import android.support.v4.app.NotificationCompat;
import android.support.v4.app.RemoteInput;
import android.util.Log;
import android.widget.RemoteViews;
import com.habitrpg.android.habitica.R;
import com.habitrpg.android.habitica.receivers.LocalNotificationActionReceiver;
import com.habitrpg.android.habitica.ui.activities.MainActivity;
import java.util.Map;
/**
* Created by keithholliday on 7/1/16.
*/
public class ReceivedPrivateMessageLocalNotification extends HabiticaLocalNotification {
@Override
public void notifyLocally(Context context, String title, String message) {
super.notifyLocally(context, title, message);
this.setNotificationActions();
NotificationManager notificationManager = (NotificationManager) context.getSystemService(context.NOTIFICATION_SERVICE);
notificationManager.notify(10, notificationBuilder.build());
}
protected void setNotificationActions() {
Intent intent = new Intent(context, LocalNotificationActionReceiver.class);
PendingIntent pendingIntent = PendingIntent.getActivity(
context,
3000,
intent,
PendingIntent.FLAG_UPDATE_CURRENT
);
notificationBuilder.setContentIntent(pendingIntent);
}
}

View file

@ -0,0 +1,38 @@
package com.habitrpg.android.habitica.helpers.notifications;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.media.RingtoneManager;
import android.net.Uri;
import android.support.v4.app.NotificationCompat;
import com.habitrpg.android.habitica.R;
import com.habitrpg.android.habitica.ui.activities.MainActivity;
import java.util.Map;
/**
* Created by keithholliday on 7/1/16.
*/
public class ReceivedSubscriptionGiftLocalNotification extends HabiticaLocalNotification {
@Override
public void notifyLocally(Context context, String title, String message) {
super.notifyLocally(context, title, message);
this.setNotificationActions();
NotificationManager notificationManager = (NotificationManager) context.getSystemService(context.NOTIFICATION_SERVICE);
notificationManager.notify(10, notificationBuilder.build());
}
protected void setNotificationActions() {
Intent intent = new Intent(context, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(
context,
3000,
intent,
PendingIntent.FLAG_UPDATE_CURRENT
);
notificationBuilder.setContentIntent(pendingIntent);
}
}

View file

@ -0,0 +1,38 @@
package com.habitrpg.android.habitica.helpers.notifications;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.media.RingtoneManager;
import android.net.Uri;
import android.support.v4.app.NotificationCompat;
import com.habitrpg.android.habitica.R;
import com.habitrpg.android.habitica.ui.activities.MainActivity;
import java.util.Map;
/**
* Created by keithholliday on 7/2/16.
*/
public class WonChallengeLocalNotification extends HabiticaLocalNotification {
@Override
public void notifyLocally(Context context, String title, String message) {
super.notifyLocally(context, title, message);
this.setNotificationActions();
NotificationManager notificationManager = (NotificationManager) context.getSystemService(context.NOTIFICATION_SERVICE);
notificationManager.notify(10, notificationBuilder.build());
}
protected void setNotificationActions() {
Intent intent = new Intent(context, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(
context,
3000,
intent,
PendingIntent.FLAG_UPDATE_CURRENT
);
notificationBuilder.setContentIntent(pendingIntent);
}
}

View file

@ -0,0 +1,97 @@
package com.habitrpg.android.habitica.receivers;
import android.app.NotificationManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.os.Bundle;
import android.util.Log;
import com.habitrpg.android.habitica.APIHelper;
import com.habitrpg.android.habitica.HabiticaApplication;
import com.habitrpg.android.habitica.R;
import com.habitrpg.android.habitica.callbacks.HabitRPGUserCallback;
import com.magicmicky.habitrpgwrapper.lib.models.HabitRPGUser;
import javax.inject.Inject;
/**
* Created by keithholliday on 6/30/16.
*/
public class LocalNotificationActionReceiver extends BroadcastReceiver implements HabitRPGUserCallback.OnUserReceived {
@Inject
public APIHelper apiHelper;
private HabitRPGUser user;
private String action;
private Resources resources;
private Intent intent;
private Context context;
@Override
public void onReceive(Context context, Intent intent) {
HabiticaApplication.getInstance(context).getComponent().inject(this);
this.resources = context.getResources();
this.action = intent.getAction();
this.intent = intent;
this.context = context;
this.apiHelper.apiService.getUser()
.compose(this.apiHelper.configureApiCallObserver())
.subscribe(new HabitRPGUserCallback(this), throwable -> {});
}
@Override
public void onUserReceived(HabitRPGUser user) {
this.user = user;
this.handleLocalNotificationAction(action);
}
private void handleLocalNotificationAction(String action) {
NotificationManager notificationManager = (NotificationManager) this.context.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.cancelAll();
//@TODO: This is a good place for a factory and event emitter pattern
if (action.equals(this.resources.getString(R.string.accept_party_invite))) {
if (this.user.getInvitations().getParty() == null) return;
String partyId = this.user.getInvitations().getParty().getId();
apiHelper.apiService.joinGroup(partyId)
.compose(apiHelper.configureApiCallObserver())
.subscribe(aVoid -> {}, throwable -> {});
} else if (action.equals(this.resources.getString(R.string.reject_party_invite))) {
if (this.user.getInvitations().getParty() == null) return;
String partyId = this.user.getInvitations().getParty().getId();
apiHelper.apiService.rejectGroupInvite(partyId)
.compose(apiHelper.configureApiCallObserver())
.subscribe(aVoid -> {}, throwable -> {});
} else if (action.equals(this.resources.getString(R.string.accept_quest_invite))) {
if (this.user.getParty() == null) return;
String partyId = this.user.getParty().getId();
apiHelper.apiService.acceptQuest(partyId)
.compose(apiHelper.configureApiCallObserver())
.subscribe(aVoid -> {}, throwable -> {});
} else if (action.equals(this.resources.getString(R.string.reject_quest_invite))) {
if (this.user.getParty() == null) return;
String partyId = this.user.getParty().getId();
apiHelper.apiService.rejectQuest(partyId)
.compose(apiHelper.configureApiCallObserver())
.subscribe(aVoid -> {}, throwable -> {});
} else if (action.equals(this.resources.getString(R.string.accept_guild_invite))) {
Bundle extras = this.intent.getExtras();
String guildId = extras.getString("groupID");
if (guildId == null) return;
apiHelper.apiService.joinGroup(guildId)
.compose(apiHelper.configureApiCallObserver())
.subscribe(aVoid -> {}, throwable -> {});
} else if (action.equals(this.resources.getString(R.string.reject_guild_invite))) {
Bundle extras = this.intent.getExtras();
String guildId = extras.getString("groupID");
if (guildId == null) return;
apiHelper.apiService.rejectGroupInvite(guildId)
.compose(apiHelper.configureApiCallObserver())
.subscribe(aVoid -> {}, throwable -> {});
}
}
}

View file

@ -84,55 +84,6 @@ public class LoginActivity extends BaseActivity
TextView mForgotPWTV;
private Menu menu;
private CallbackManager callbackManager;
private View.OnClickListener mLoginNormalClick = new View.OnClickListener() {
@Override
public void onClick(View v) {
mProgressBar.setVisibility(View.VISIBLE);
if (isRegistering) {
String username, email, password, cpassword;
username = String.valueOf(mUsernameET.getText()).trim();
email = String.valueOf(mEmail.getText()).trim();
password = String.valueOf(mPasswordET.getText());
cpassword = String.valueOf(mConfirmPassword.getText());
if (username.length() == 0 || password.length() == 0 || email.length() == 0 || cpassword.length() == 0) {
showValidationError(R.string.login_validation_error_fieldsmissing);
return;
}
apiHelper.registerUser(username, email, password, cpassword)
.compose(apiHelper.configureApiCallObserver())
.subscribe(LoginActivity.this, throwable -> {
hideProgress();
});
} else {
String username, password;
username = String.valueOf(mUsernameET.getText()).trim();
password = String.valueOf(mPasswordET.getText());
if (username.length() == 0 || password.length() == 0) {
showValidationError(R.string.login_validation_error_fieldsmissing);
return;
}
apiHelper.connectUser(username, password)
.compose(apiHelper.configureApiCallObserver())
.subscribe(LoginActivity.this, throwable -> {
hideProgress();
});
}
}
};
private View.OnClickListener mForgotPWClick = v -> {
String url = BuildConfig.BASE_URL;
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(url));
startActivity(i);
};
public static void show(final View v) {
v.setVisibility(View.VISIBLE);
}
public static void hide(final View v) {
v.setVisibility(View.GONE);
}
@Override
protected int getLayoutResId() {
@ -214,6 +165,54 @@ public class LoginActivity extends BaseActivity
hide(this.mConfirmPasswordRow);
}
}
}
private View.OnClickListener mLoginNormalClick = new View.OnClickListener() {
@Override
public void onClick(View v) {
mProgressBar.setVisibility(View.VISIBLE);
if (isRegistering) {
String username, email,password,cpassword;
username = String.valueOf(mUsernameET.getText()).trim();
email = String.valueOf(mEmail.getText()).trim();
password = String.valueOf(mPasswordET.getText());
cpassword = String.valueOf(mConfirmPassword.getText());
if (username.length() == 0 || password.length() == 0 || email.length() == 0 || cpassword.length() == 0) {
showValidationError(R.string.login_validation_error_fieldsmissing);
return;
}
apiHelper.registerUser(username,email,password, cpassword)
.compose(apiHelper.configureApiCallObserver())
.subscribe(LoginActivity.this, throwable -> {hideProgress();});
} else {
String username,password;
username = String.valueOf(mUsernameET.getText()).trim();
password = String.valueOf(mPasswordET.getText());
if (username.length() == 0 || password.length() == 0) {
showValidationError(R.string.login_validation_error_fieldsmissing);
return;
}
apiHelper.connectUser(username,password)
.compose(apiHelper.configureApiCallObserver())
.subscribe(LoginActivity.this, throwable -> {hideProgress();});
}
}
};
private View.OnClickListener mForgotPWClick = v -> {
String url = BuildConfig.BASE_URL;
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(url));
startActivity(i);
};
public static void show(final View v) {
v.setVisibility(View.VISIBLE);
}
public static void hide(final View v) {
v.setVisibility(View.GONE);
}
private void startMainActivity() {

View file

@ -32,6 +32,7 @@ import com.habitrpg.android.habitica.events.commands.OpenMenuItemCommand;
import com.habitrpg.android.habitica.events.commands.SellItemCommand;
import com.habitrpg.android.habitica.events.commands.UnlockPathCommand;
import com.habitrpg.android.habitica.events.commands.UpdateUserCommand;
import com.habitrpg.android.habitica.helpers.notifications.PushNotificationManager;
import com.habitrpg.android.habitica.ui.AvatarView;
import com.habitrpg.android.habitica.ui.AvatarWithBarsViewModel;
import com.habitrpg.android.habitica.ui.TutorialView;
@ -206,6 +207,8 @@ public class MainActivity extends BaseActivity implements Action1<Throwable>, Ha
return (Math.round(value * Math.pow(10, n))) / (Math.pow(10, n));
}
PushNotificationManager pushNotificationManager;
@Override
protected int getLayoutResId() {
return R.layout.activity_main;
@ -222,6 +225,8 @@ public class MainActivity extends BaseActivity implements Action1<Throwable>, Ha
//Check if reminder alarm is set
scheduleReminder(this);
pushNotificationManager = PushNotificationManager.getInstance(this);
new Select().from(HabitRPGUser.class).where(Condition.column("id").eq(hostConfig.getUser())).async().querySingle(userTransactionListener);
setupToolbar(toolbar);
@ -349,8 +354,9 @@ public class MainActivity extends BaseActivity implements Action1<Throwable>, Ha
displayDeathDialogIfNeeded();
if (!fromLocalDb) {
displayNewInboxMessagesBadge();
pushNotificationManager.setUser(user);
pushNotificationManager.addPushDeviceUsingStoredToken();
// Update the oldEntries
new Thread(() -> {

View file

@ -6,6 +6,7 @@ import com.habitrpg.android.habitica.R;
import com.habitrpg.android.habitica.components.AppComponent;
import com.habitrpg.android.habitica.ui.fragments.preferences.AccountDetailsFragment;
import com.habitrpg.android.habitica.ui.fragments.preferences.PreferencesFragment;
import com.habitrpg.android.habitica.ui.fragments.preferences.PushNotificationsPreferencesFragment;
import android.content.Context;
import android.content.SharedPreferences;
@ -88,6 +89,10 @@ public class PrefsActivity extends BaseActivity implements
if (preferenceScreen.getKey().equals("accountDetails")) {
fragment = new AccountDetailsFragment();
}
if (preferenceScreen.getKey().equals("pushNotifications")) {
fragment = new PushNotificationsPreferencesFragment();
}
return fragment;
}
}

View file

@ -4,6 +4,7 @@ import com.habitrpg.android.habitica.APIHelper;
import com.habitrpg.android.habitica.HabiticaApplication;
import com.habitrpg.android.habitica.NotificationPublisher;
import com.habitrpg.android.habitica.R;
import com.habitrpg.android.habitica.helpers.notifications.PushNotificationManager;
import com.habitrpg.android.habitica.prefs.TimePreference;
import com.habitrpg.android.habitica.ui.activities.ClassSelectionActivity;
import com.habitrpg.android.habitica.ui.activities.MainActivity;
@ -21,6 +22,8 @@ import android.content.SharedPreferences;
import android.os.Bundle;
import android.support.v7.app.AlertDialog;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceScreen;
import android.util.Log;
import java.util.Calendar;
@ -33,8 +36,11 @@ public class PreferencesFragment extends BasePreferencesFragment implements
public APIHelper apiHelper;
private Context context;
private TimePreference timePreference;
private PreferenceScreen pushNotificationsPreference;
private Preference classSelectionPreference;
private HabitRPGUser user;
private PushNotificationManager pushNotificationManager;
private TransactionListener<HabitRPGUser> userTransactionListener = new TransactionListener<HabitRPGUser>() {
@Override
public void onResultReceived(HabitRPGUser habitRPGUser) {
@ -64,6 +70,7 @@ public class PreferencesFragment extends BasePreferencesFragment implements
new Select().from(HabitRPGUser.class).where(Condition.column("id").eq(userID)).async().querySingle(userTransactionListener);
}
pushNotificationManager = PushNotificationManager.getInstance(this.getActivity());
}
@Override
@ -72,6 +79,12 @@ public class PreferencesFragment extends BasePreferencesFragment implements
boolean useReminder = getPreferenceManager().getSharedPreferences().getBoolean("use_reminder", false);
timePreference.setEnabled(useReminder);
pushNotificationsPreference = (PreferenceScreen) findPreference("pushNotifications");
boolean userPushNotifications = getPreferenceManager().getSharedPreferences().getBoolean("usePushNotifications", true);
pushNotificationsPreference.setEnabled(userPushNotifications);
classSelectionPreference = findPreference("choose_class");
classSelectionPreference.setVisible(false);
}
@ -176,6 +189,14 @@ public class PreferencesFragment extends BasePreferencesFragment implements
} else if (key.equals("reminder_time")) {
removeNotifications();
scheduleNotifications();
} else if (key.equals("usePushNotifications")) {
boolean userPushNotifications = sharedPreferences.getBoolean(key, false);
pushNotificationsPreference.setEnabled(userPushNotifications);
if (userPushNotifications) {
pushNotificationManager.addPushDeviceUsingStoredToken();
} else {
pushNotificationManager.removePushDeviceUsingStoredToken();
}
}
}

View file

@ -0,0 +1,31 @@
package com.habitrpg.android.habitica.ui.fragments.preferences;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.SharedPreferences;
import android.support.v7.preference.Preference;
import android.widget.Toast;
import com.habitrpg.android.habitica.R;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
/**
* Created by keithholliday on 6/27/16.
*/
public class PushNotificationsPreferencesFragment extends BasePreferencesFragment implements
SharedPreferences.OnSharedPreferenceChangeListener {
@Override
protected void setupPreferences() {
}
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
}
}

View file

@ -208,6 +208,9 @@ public interface ApiService {
@POST("groups/{gid}/invite")
Observable<Void> inviteToGroup(@Path("gid") String groupId, @Body Map<String, Object> inviteData);
@POST("groups/{gid}/reject-invite")
Observable<Void> rejectGroupInvite(@Path("gid") String groupId);
@POST("groups/{gid}/quests/accept")
Observable<Void> acceptQuest(@Path("gid") String groupId);
@ -235,10 +238,17 @@ public interface ApiService {
//Members URL
@POST("members/send-private-message")
Observable<PostChatMessageResult> postPrivateMessage(@Body HashMap<String, String> messageDetails);
@GET("shops/{identifier}")
Observable<Shop> fetchShopInventory(@Path("identifier") String identifier);
//Push notifications
@POST("user/push-devices")
Observable<Void> addPushDevice(@Body Map<String, String> pushDeviceData);
@DELETE("user/push-devices/{regId}")
Observable<Void> deletePushDevice(@Path("regId") String regId);
//DEBUG: These calls only work on a local development server
@POST("debug/add-ten-gems")

View file

@ -4,6 +4,7 @@ import com.google.gson.annotations.SerializedName;
import com.habitrpg.android.habitica.HabitDatabase;
import com.habitrpg.android.habitica.ui.AvatarView;
import com.magicmicky.habitrpgwrapper.lib.models.invitations.Invitations;
import com.magicmicky.habitrpgwrapper.lib.models.tasks.Task;
import com.magicmicky.habitrpgwrapper.lib.models.tasks.TasksOrder;
import com.raizlabs.android.dbflow.annotation.Column;
@ -92,6 +93,14 @@ public class HabitRPGUser extends BaseModel {
foreignColumnName = "user_id")})
private ContributorInfo contributor;
@Column
@ForeignKey(references = {@ForeignKeyReference(columnName = "invitations_id",
columnType = String.class,
foreignColumnName = "user_id")})
private Invitations invitations;
private List<PushDevice> pushDevices = new ArrayList<PushDevice>();
private Purchases purchased;
private TasksOrder tasksOrder;
@ -145,6 +154,13 @@ public class HabitRPGUser extends BaseModel {
this.contributor = contributor;
}
public Invitations getInvitations() {
return invitations;
}
public void setInvitations(Invitations invitations) {
this.invitations = invitations;
}
public UserParty getParty() {
return party;
@ -282,6 +298,14 @@ public class HabitRPGUser extends BaseModel {
this.tasksOrder = tasksOrder;
}
public List<PushDevice> getPushDevices() {
return this.pushDevices;
}
public void setPushDevices(List<PushDevice> pushDevices) {
this.pushDevices = pushDevices;
}
@Override
public void save() {
// We need to set the user_id to all other objects
@ -293,6 +317,9 @@ public class HabitRPGUser extends BaseModel {
authentication.user_id = id;
flags.user_id = id;
if (contributor != null) { contributor.user_id = id; }
contributor.user_id = id;
invitations.user_id = id;
ArrayList<Task> allTasks = new ArrayList<Task>();
if (dailys != null) {

View file

@ -0,0 +1,34 @@
package com.magicmicky.habitrpgwrapper.lib.models;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
/**
* Created by keithholliday on 7/5/16.
*/
public class PushDevice {
@SerializedName("regId")
@Expose
private String regId;
@SerializedName("type")
@Expose
private String type;
public String getRegId() {
return this.regId;
}
public void setRegId(String regId) {
this.regId = regId;
}
public String getType() {
return this.type;
}
public void setType(String type) {
this.type = type;
}
}

View file

@ -0,0 +1,76 @@
package com.magicmicky.habitrpgwrapper.lib.models.invitations;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
/**
* Created by keithholliday on 7/2/16.
*/
public class GuildInvite {
@SerializedName("inviter")
@Expose
private String inviter;
@SerializedName("name")
@Expose
private String name;
@SerializedName("id")
@Expose
private String id;
/**
*
* @return
* The inviter
*/
public String getInviter() {
return inviter;
}
/**
*
* @param inviter
* The inviter
*/
public void setInviter(String inviter) {
this.inviter = inviter;
}
/**
*
* @return
* The name
*/
public String getName() {
return name;
}
/**
*
* @param name
* The name
*/
public void setName(String name) {
this.name = name;
}
/**
*
* @return
* The id
*/
public String getId() {
return id;
}
/**
*
* @param id
* The id
*/
public void setId(String id) {
this.id = id;
}
}

View file

@ -0,0 +1,71 @@
package com.magicmicky.habitrpgwrapper.lib.models.invitations;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
import com.habitrpg.android.habitica.HabitDatabase;
import com.magicmicky.habitrpgwrapper.lib.models.invitations.PartyInvite;
import com.raizlabs.android.dbflow.annotation.Column;
import com.raizlabs.android.dbflow.annotation.NotNull;
import com.raizlabs.android.dbflow.annotation.PrimaryKey;
import com.raizlabs.android.dbflow.annotation.Table;
import com.raizlabs.android.dbflow.structure.BaseModel;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* Created by keithholliday on 7/2/16.
*/
@Table(databaseName = HabitDatabase.NAME)
public class Invitations extends BaseModel {
@Column
@PrimaryKey
@NotNull
public String user_id;
@SerializedName("party")
@Expose
private PartyInvite party;
@SerializedName("guilds")
@Expose
private List<GuildInvite> guilds = new ArrayList<GuildInvite>();
/**
*
* @return
* The party invite
*/
public PartyInvite getParty() {
return party;
}
/**
*
* @param party
* The party
*/
public void setParty(PartyInvite party) {
this.party = party;
}
/**
*
* @return
* The guilds invite
*/
public List<GuildInvite> getGuilds() {
return guilds;
}
/**
*
* @param guilds
* The guilds
*/
public void setGuilds(List<GuildInvite> guilds) {
this.guilds = guilds;
}
}

View file

@ -0,0 +1,73 @@
package com.magicmicky.habitrpgwrapper.lib.models.invitations;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
/**
* Created by keithholliday on 7/2/16.
*/
public class PartyInvite {
@SerializedName("id")
@Expose
private String id;
@SerializedName("name")
@Expose
private String name;
@SerializedName("inviter")
@Expose
private String inviter;
/**
*
* @return
* The id
*/
public String getId() {
return id;
}
/**
*
* @param id
* The id
*/
public void setId(String id) {
this.id = id;
}
/**
*
* @return
* The name
*/
public String getName() {
return name;
}
/**
*
* @param name
* The name
*/
public void setName(String name) {
this.name = name;
}
/**
*
* @return
* The inviter
*/
public String getInviter() {
return inviter;
}
/**
*
* @param inviter
* The inviter
*/
public void setInviter(String inviter) {
this.inviter = inviter;
}
}

View file

@ -12,7 +12,7 @@ It's also on Google Play:
src="https://play.google.com/intl/en_us/badges/images/generic/en-play-badge.png" />
</a>
Having the application installed is a good way to be notified of new releases. However, clicking "Watch" on this
Having the application installed is a good way to be notified of new releases. However, clicking "Watch" on this
repository will allow GitHub to email you whenever we publish a release.
@ -54,6 +54,7 @@ Setup Habitica build config files by simply copying the example habitica files.
$ cp habitica.properties.example habitica.properties
$ cp habitica.resources.example habitica.resources
$ cp Habitica/google-services.json.example Habitica/google-services.json (Get .json from Firebase Console)
Note: this is the default production `habitica.properties` file for habitica.com. If you
want to use a local habitica server, please modify the values in the properties file accordingly.

View file

@ -8,6 +8,7 @@ buildscript {
classpath 'com.android.tools.build:gradle:2.1.2'
classpath 'com.android.databinding:dataBinder:1.0-rc4'
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
classpath 'com.google.gms:google-services:3.0.0'
}
}