mirror of
https://github.com/sudoxnym/habitica-android.git
synced 2026-04-14 19:56:32 +00:00
Merge branch 'develop' of https://github.com/HabitRPG/habitrpg-android into full-profile
Conflicts: Habitica/src/main/java/com/habitrpg/android/habitica/components/AppComponent.java
This commit is contained in:
commit
127464537d
72 changed files with 2202 additions and 139 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -54,3 +54,4 @@ fabric.properties
|
|||
Habitica/res/values/secret_strings.xml
|
||||
habitica.properties
|
||||
habitica.resources
|
||||
Habitica/google-services.json
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@
|
|||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
package="com.habitrpg.android.habitica"
|
||||
android:versionCode="108"
|
||||
android:versionName="0.0.33"
|
||||
android:versionCode="111"
|
||||
android:versionName="0.0.33.1"
|
||||
android:screenOrientation="portrait"
|
||||
android:installLocation="auto" >
|
||||
|
||||
|
|
@ -132,12 +132,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="ACCEPT_PARTY_INVITE"/>
|
||||
<action android:name="REJECT_PARTY_INVITE"/>
|
||||
<action android:name="ACCEPT_QUEST_INVITE"/>
|
||||
<action android:name="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"
|
||||
|
|
|
|||
140
Habitica/AndroidManifestTesting.xml
Normal file
140
Habitica/AndroidManifestTesting.xml
Normal file
|
|
@ -0,0 +1,140 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
package="com.habitrpg.android.habitica"
|
||||
android:versionCode="104"
|
||||
android:versionName="0.0.32"
|
||||
android:screenOrientation="portrait"
|
||||
android:installLocation="auto" >
|
||||
|
||||
<uses-sdk
|
||||
android:minSdkVersion="15"
|
||||
android:targetSdkVersion="24" />
|
||||
|
||||
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="com.android.vending.BILLING" />
|
||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
|
||||
|
||||
<application
|
||||
android:name=".HabiticaApplication"
|
||||
android:allowBackup="true"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:theme="@style/AppTheme">
|
||||
<activity
|
||||
android:name=".ui.activities.MainActivity"
|
||||
android:label="@string/app_name"
|
||||
android:windowSoftInputMode="stateHidden|adjustPan"
|
||||
android:screenOrientation="portrait">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".ui.activities.PrefsActivity"
|
||||
android:parentActivityName=".ui.activities.MainActivity"
|
||||
android:label="@string/PS_settings_title"
|
||||
android:screenOrientation="portrait"
|
||||
tools:ignore="UnusedAttribute">
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".ui.activities.LoginActivity"
|
||||
android:label="@string/LoginActivityName"
|
||||
android:theme="@style/AppThemeWithActionBarBlackText"
|
||||
android:windowSoftInputMode="adjustResize"
|
||||
android:screenOrientation="portrait">
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".ui.activities.IntroActivity"
|
||||
android:windowSoftInputMode="adjustResize"
|
||||
android:screenOrientation="portrait">
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".ui.activities.SetupActivity"
|
||||
android:windowSoftInputMode="adjustResize"
|
||||
android:screenOrientation="portrait">
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".ui.activities.SkillTasksActivity"
|
||||
android:label="@string/app_name"
|
||||
android:screenOrientation="portrait">
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".ui.activities.AboutActivity"
|
||||
android:theme="@style/AppThemeWithActionBarBlackText"
|
||||
android:screenOrientation="portrait"/>
|
||||
<activity
|
||||
android:name=".ui.activities.TaskFormActivity"
|
||||
android:theme="@style/AppThemeWithActionBarBlackText"
|
||||
android:parentActivityName=".ui.activities.MainActivity"
|
||||
android:screenOrientation="portrait"
|
||||
tools:ignore="UnusedAttribute">
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value=".ui.activities.MainActivity" />
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".ui.activities.GroupFormActivity"
|
||||
android:theme="@style/AppThemeWithActionBarBlackText"
|
||||
android:parentActivityName=".ui.activities.MainActivity"
|
||||
android:screenOrientation="portrait"
|
||||
tools:ignore="UnusedAttribute">
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value=".ui.activities.MainActivity" />
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".ui.activities.ClassSelectionActivity"
|
||||
android:theme="@style/AppThemeWithActionBarBlackText"
|
||||
android:parentActivityName=".ui.activities.MainActivity"
|
||||
android:screenOrientation="portrait"
|
||||
tools:ignore="UnusedAttribute"
|
||||
android:label="@string/select_class">
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value=".ui.activities.MainActivity" />
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".ui.activities.PartyInviteActivity"
|
||||
android:theme="@style/AppThemeWithActionBarBlackText"
|
||||
android:screenOrientation="portrait"
|
||||
tools:ignore="UnusedAttribute"
|
||||
android:label="@string/invite_users">
|
||||
</activity>
|
||||
<activity android:name="com.facebook.FacebookActivity"
|
||||
android:configChanges=
|
||||
"keyboard|keyboardHidden|screenLayout|screenSize|orientation"
|
||||
android:screenOrientation="portrait"
|
||||
android:theme="@android:style/Theme.Translucent.NoTitleBar"
|
||||
android:label="@string/app_name" />
|
||||
<activity android:name=".ui.activities.MaintenanceActivity"
|
||||
android:screenOrientation="portrait"
|
||||
android:theme="@style/Theme.AppCompat.Light.NoActionBar" />
|
||||
<receiver android:process=":remote" android:name=".NotificationPublisher" />
|
||||
|
||||
<receiver android:process=":remote" android:name=".receivers.TaskReceiver"></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>
|
||||
|
||||
<provider
|
||||
android:name="android.support.v4.content.FileProvider"
|
||||
android:authorities="com.habitrpg.android.habitica.fileprovider"
|
||||
android:grantUriPermissions="true"
|
||||
android:exported="false">
|
||||
<meta-data
|
||||
android:name="android.support.FILE_PROVIDER_PATHS"
|
||||
android:resource="@xml/filepaths" />
|
||||
</provider>
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
|
|
@ -71,11 +71,11 @@ dependencies {
|
|||
compile('com.mikepenz:materialdrawer:5.3.6@aar') {
|
||||
transitive = true
|
||||
}
|
||||
compile 'com.android.support:appcompat-v7:24.0.0'
|
||||
compile 'com.android.support:design:24.0.0'
|
||||
compile 'com.android.support:gridlayout-v7:24.0.0'
|
||||
compile 'com.android.support:recyclerview-v7:24.0.0'
|
||||
compile 'com.android.support:preference-v14:24.0.0'
|
||||
compile 'com.android.support:appcompat-v7:24.1.1'
|
||||
compile 'com.android.support:design:24.1.1'
|
||||
compile 'com.android.support:gridlayout-v7:24.1.1'
|
||||
compile 'com.android.support:recyclerview-v7:24.1.1'
|
||||
compile 'com.android.support:preference-v14:24.1.1'
|
||||
compile 'com.android.support:multidex:1.0.1'
|
||||
|
||||
// Image Loading/Caching
|
||||
|
|
@ -128,24 +128,32 @@ dependencies {
|
|||
exclude module: 'bolts-android'
|
||||
}
|
||||
//Tests
|
||||
compile 'com.android.support:appcompat-v7:23.0'
|
||||
compile 'com.android.support:appcompat-v7:24.1.1'
|
||||
testCompile "junit:junit:4.10"
|
||||
testCompile "org.assertj:assertj-core:1.7.0"
|
||||
testCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.3.1'
|
||||
testCompile "org.robolectric:robolectric:3.2-SNAPSHOT"
|
||||
testCompile 'org.robolectric:shadows-multidex:3.0'
|
||||
testCompile "org.robolectric:shadows-support-v4:3.0"
|
||||
testCompile "org.robolectric:robolectric:3.1"
|
||||
testCompile 'org.robolectric:shadows-multidex:3.1'
|
||||
testCompile "org.robolectric:shadows-support-v4:3.1"
|
||||
testCompile "org.mockito:mockito-core:1.10.19"
|
||||
|
||||
//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 {
|
||||
compileSdkVersion 24
|
||||
buildToolsVersion "23.0.3"
|
||||
|
||||
defaultConfig {
|
||||
applicationId "com.habitrpg.android.habitica"
|
||||
}
|
||||
|
||||
lintOptions {
|
||||
abortOnError false
|
||||
}
|
||||
|
|
@ -184,7 +192,7 @@ android {
|
|||
assets.srcDirs = ['assets']
|
||||
}
|
||||
robolectric {
|
||||
manifest.srcFile 'AndroidManifest.xml'
|
||||
manifest.srcFile 'AndroidManifestTesting.xml'
|
||||
java.srcDir file('src/test/java/')
|
||||
res.srcDirs = ['res']
|
||||
}
|
||||
|
|
@ -276,3 +284,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'
|
||||
73
Habitica/google-services.json.example
Normal file
73
Habitica/google-services.json.example
Normal 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"
|
||||
}
|
||||
|
|
@ -2,9 +2,9 @@
|
|||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:fresco="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/fullprofile_scrollview"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:id="@+id/fullprofile_scrollview">
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
|
|
@ -187,10 +187,10 @@
|
|||
</android.support.v7.widget.CardView>
|
||||
|
||||
<android.support.v7.widget.CardView
|
||||
android:id="@+id/costume_group"
|
||||
style="@style/CardView.Default"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/costume_group">
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
|
|
@ -233,10 +233,10 @@
|
|||
android:weightSum="1">
|
||||
|
||||
<TableLayout
|
||||
android:id="@+id/attributes_table"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:stretchColumns="0,1,2,3,4"
|
||||
android:id="@+id/attributes_table">
|
||||
android:stretchColumns="0,1,2,3,4">
|
||||
|
||||
<TableRow android:layout_height="wrap_content">
|
||||
<!-- Headers -->
|
||||
|
|
@ -279,5 +279,38 @@
|
|||
android:indeterminate="true" />
|
||||
</LinearLayout>
|
||||
</android.support.v7.widget.CardView>
|
||||
|
||||
|
||||
<android.support.v7.widget.CardView
|
||||
style="@style/CardView.Default"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:padding="5dp"
|
||||
android:weightSum="1">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Pets & Mounts"
|
||||
android:textSize="@dimen/abc_text_size_title_material"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<TableLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:stretchColumns="0,1,2,3,4">
|
||||
|
||||
<TableRow android:layout_height="wrap_content">
|
||||
|
||||
</TableRow>
|
||||
</TableLayout>
|
||||
</LinearLayout>
|
||||
</android.support.v7.widget.CardView>
|
||||
|
||||
</LinearLayout>
|
||||
</ScrollView>
|
||||
|
|
@ -9,6 +9,11 @@
|
|||
android:icon="@drawable/ic_action_chat"
|
||||
android:title="@string/send_pm" />
|
||||
<group>
|
||||
<item
|
||||
android:id="@+id/menu.chat.copy"
|
||||
android:icon="@drawable/ic_action_warning"
|
||||
app:showAsAction="always|withText"
|
||||
android:title="@string/copy_chat_message" />
|
||||
<item
|
||||
android:id="@+id/menu.chat.flag"
|
||||
android:icon="@drawable/ic_action_warning"
|
||||
|
|
|
|||
20
Habitica/res/values-bg/strings.sidebar.xml
Normal file
20
Habitica/res/values-bg/strings.sidebar.xml
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<resources>
|
||||
<string name="sidebar.tasks">Задачи</string>
|
||||
<string name="sidebar.skills">Умения</string>
|
||||
<string name="sidebar.section.social">Общност</string>
|
||||
<string name="sidebar.inbox">Входящи</string>
|
||||
<string name="sidebar.tavern">Кръчма</string>
|
||||
<string name="sidebar.party">Група</string>
|
||||
<string name="sidebar.purchaseGems">Купуване на диаманти</string>
|
||||
<string name="sidebar.guilds">Гилдии</string>
|
||||
<string name="sidebar.challenges">Предизвикателства</string>
|
||||
<string name="sidebar.section.inventory">Чанта</string>
|
||||
<string name="sidebar.avatar">Герой</string>
|
||||
<string name="sidebar.equipment">Екипировка</string>
|
||||
<string name="sidebar.stable">Конюшня</string>
|
||||
<string name="sidebar.news">Новини</string>
|
||||
<string name="sidebar.settings">Настройки</string>
|
||||
<string name="sidebar.about">Относно</string>
|
||||
<string name="sidebar_shops">Магазини</string>
|
||||
</resources>
|
||||
14
Habitica/res/values-bg/strings.tutorial.xml
Normal file
14
Habitica/res/values-bg/strings.tutorial.xml
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<resources>
|
||||
<string name="tutorial_habits">Отбелязвайте положителните си навици, за да получавате злато и опит! Отрицателните навици ще наранят героя Ви, ако ги докоснете, така че ги избягвайте в истинския живот!</string>
|
||||
<string name="tutorial_dailies">Побеждавайте своите повтарящи се ежедневни задачи, за да печелите злато и опит. Внимание! Ежедневните задачи ще наранят героя Ви, ако не ги изпълните навреме.</string>
|
||||
<string name="tutorial_todos">Завършвайте задачите си за изпълнение в истинския живот, а след това ги отбелязвайте тук за ЗЛАТО и ОПИТ; така ще можете да отключвате награди и нови функционалности!</string>
|
||||
<string name="tutorial_rewards">Това са наградите Ви! Печелете злато като изпълнявате истинските си навици, ежедневни задачи и задачи за изпълнение. След това го харчете за награди в играта или персонализирани такива за истинския живот!</string>
|
||||
<string name="tutorial_equipment">Когато купувате екипировка, тя се появява тук. Бойното снаряжение променя атрибутите Ви, а костюмът (ако е включен) влияе на това какво носи героят Ви.</string>
|
||||
<string name="tutorial_items">Печелете предмети като изпълнявате задачи и качвате нива. Докоснете предмет, за да го използвате!</string>
|
||||
<string name="tutorial_pets">Когато изпълнявате задачите си в истинския живот, имате шанс на случаен принцип да Ви се паднат яйца и отвари. Комбинирайте ги, за да си излюпите любимци.</string>
|
||||
<string name="tutorial_skills">Уменията са специални способности, които имат мощни ефекти! Докоснете умение, за да го използвате. Това ще Ви струва малко мана (синята лента), която се възстановява при влизане в играта всеки ден, както и като изпълнявате задачите от истинския си живот. Прегледайте ЧЗВ в менюто за повече информация!</string>
|
||||
<string name="tutorial_party">Тук е мястото, където заедно с приятелите си можете взаимно да се държите отговорни за изпълнението на целите си, както и да се биете срещу чудовища със задачите си!</string>
|
||||
<string name="tutorial_tavern">Добре дошли в кръчмата — обществено място за разговори, достъпно за хора от всички възрасти! Тук можете да разговаряте за продуктивността си и да задавате въпроси. Приятно прекарване!</string>
|
||||
<string name="tutorial_classes">Изберете дали да бъдете воин, магьосник, лечител или мошеник! Всеки клас има уникална екипировка и умения. Докоснете (?), за да научите повече!</string>
|
||||
</resources>
|
||||
344
Habitica/res/values-bg/strings.xml
Normal file
344
Habitica/res/values-bg/strings.xml
Normal file
|
|
@ -0,0 +1,344 @@
|
|||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<resources>
|
||||
<string name="app_name">Хабитика</string>
|
||||
<string name="action_refresh">Опресняване</string>
|
||||
<string name="XP_default">Опит</string>
|
||||
<string name="HP_default">Здраве</string>
|
||||
<string name="MP_default">Мана</string>
|
||||
<string name="ERR_pb_barcode">Настройките не могат да бъдат заредени от кода</string>
|
||||
<!--Prefs-->
|
||||
<string name="PS_settings_title">Настройки</string>
|
||||
<string name="SP_address_hint">Вашият персонализиран сървър</string>
|
||||
<string name="SP_userID_title">Потребителски идентификатор</string>
|
||||
<string name="SP_userID_summary">Вашият потребителски идентификатор</string>
|
||||
<string name="SP_APIToken_title">Жетон за ППИ</string>
|
||||
<string name="SP_APIToken_summary">Вашият жетон за ППИ</string>
|
||||
<string name="PS_contact_title">Свържете се с мен</string>
|
||||
<string name="unknown_error">Възникна грешка…</string>
|
||||
<string name="pref_account_header">Профил</string>
|
||||
<string name="pref_reminder_header">Ежедневно напомняне</string>
|
||||
<string name="pref_reminder_checkbox">Включване на напомнянето</string>
|
||||
<string name="pref_reminder_picker">Задаване на времето за напомняне</string>
|
||||
<!--Adding tasks-->
|
||||
<string name="task_value">Стойност</string>
|
||||
<string name="new_todo">Нова задача за изпълнение</string>
|
||||
<string name="new_reward">Нова награда</string>
|
||||
<string name="new_daily">Нова ежедневна задача</string>
|
||||
<string name="new_habit">Нов навик</string>
|
||||
<string name="action_edit">Редактиране</string>
|
||||
<string name="action_delete">Изтриване</string>
|
||||
<string name="action_cancel">Отказ</string>
|
||||
<string name="login_btn">Вход</string>
|
||||
<string name="register_btn">Регистрация</string>
|
||||
<string name="username">Потребителско име</string>
|
||||
<string name="email_username">Е-поща или потребителско име</string>
|
||||
<string name="password">Парола</string>
|
||||
<string name="emailAddress">Е-поща</string>
|
||||
<string name="confirmpassword">Потвърдете паролата</string>
|
||||
<string name="logout">Изход</string>
|
||||
<string name="logout_description">Излизане от Вашия профил</string>
|
||||
<string name="account_details">Подробности за профила</string>
|
||||
<string name="LoginActivityName">Добре дошли</string>
|
||||
<string name="string_revive">Съживяване</string>
|
||||
<string name="please_connect">Моля, свържете се чрез приложението, преди да използвате джаджа</string>
|
||||
<string name="about.title">Относно</string>
|
||||
<string name="about.libraries">Библиотеки</string>
|
||||
<string name="about.versionhistory">История на версиите</string>
|
||||
<string name="about.habitica_open_source">Хабитика е софтуер с отворен код, който е наличен в Github</string>
|
||||
<string name="about.rate_our_app">Оценете приложението</string>
|
||||
<string name="about.give_us_feedback">Изпратете ни отзивите си!</string>
|
||||
<string name="about.bugreport">Докладване на грешка</string>
|
||||
<string name="about.source_code">Изходен код</string>
|
||||
<!--Network Errors-->
|
||||
<string name="network_error_title">Грешка при свързване</string>
|
||||
<string name="network_error_no_network_body">Нямате връзка с Интернет.</string>
|
||||
<string name="internal_error_api">Изглежда има проблем със сървъра. Опитайте отново по-късно.</string>
|
||||
<string name="authentication_error_title">Грешка при удостоверяване</string>
|
||||
<string name="authentication_error_body">Потребителското име и/или паролата е грешна.</string>
|
||||
<string name="login_validation_error_title">Грешка при проверяването</string>
|
||||
<string name="login_validation_error_fieldsmissing">Трябва да попълните всички полета.</string>
|
||||
<string name="save_changes">Запазване</string>
|
||||
<string name="notes">Бележки</string>
|
||||
<string name="text">Текст</string>
|
||||
<string name="difficulty">Трудност</string>
|
||||
<string name="tags">Етикети</string>
|
||||
<string name="trivial">Елементарно</string>
|
||||
<string name="easy">Лесно</string>
|
||||
<string name="medium">Средно</string>
|
||||
<string name="hard">Трудно</string>
|
||||
<string name="start_date">Начална дата</string>
|
||||
<string name="positive_habit_form">Положителен ( + )</string>
|
||||
<string name="negative_habit_form">Отрицателен ( - )</string>
|
||||
<string name="checklist">Подзадачи</string>
|
||||
<string name="reminders">Напомняния</string>
|
||||
<string name="actions">Действия</string>
|
||||
<string name="attributes">Атрибути</string>
|
||||
<string name="physical">Физическа</string>
|
||||
<string name="mental">Умствена</string>
|
||||
<string name="social">Обществена</string>
|
||||
<string name="other">Други</string>
|
||||
<string name="frequency">Честота</string>
|
||||
<string name="frequency_weekly">В определени дни от седмицата</string>
|
||||
<string name="frequency_daily">На всеки Х дни</string>
|
||||
<string name="monday">Понеделник</string>
|
||||
<string name="tuesday">Вторник</string>
|
||||
<string name="wednesday">Сряда</string>
|
||||
<string name="thursday">Четвъртък</string>
|
||||
<string name="friday">Петък</string>
|
||||
<string name="saturday">Събота</string>
|
||||
<string name="sunday">Неделя</string>
|
||||
<string name="levelup_header">Вдигнахте ниво!</string>
|
||||
<string name="levelup_detail">Изпълнявайки целите си в истинския живот, Вие достигнахте ниво %1$d!</string>
|
||||
<string name="levelup_health">Вие бяхте излекуван(а) напълно!</string>
|
||||
<string name="levelup_button">Ура!</string>
|
||||
<string name="faint_subtitle">Не се отчайвайте!</string>
|
||||
<string name="faint_penalty_body">Изгубихте ниво, всичкото си злато и един предмет от екипировката си, но можете да си ги върнете с усърдна работа! Късмет — ще се справите.</string>
|
||||
<string name="faint_header">Здравето Ви свърши!</string>
|
||||
<string name="faint_button">Възстановете здравето си и опитайте отново</string>
|
||||
<string name="filter">Филтър</string>
|
||||
<string name="profile_image">Профилно изображение</string>
|
||||
<string name="mana_price_button" formatted="false">%d ТМ</string>
|
||||
<string name="used_skill" formatted="false">Използвахте %1$s за %2$d точки мана.</string>
|
||||
<string name="new_checklist_item">нова подзадача</string>
|
||||
<string name="add_checklist_item">Добавяне</string>
|
||||
<string name="reminder_title">Не забравяйте да изпълнявате ежедневните си задачи!</string>
|
||||
<string name="skill_progress_title">Използване на умение</string>
|
||||
<string name="coming_soon">Очаквайте скоро</string>
|
||||
<string name="chat_flag_confirmation">Наистина ли искате да докладвате това съобщение за нарушение?</string>
|
||||
<string name="flag_confirm">Докладване на съобщението</string>
|
||||
<string name="unlock_lvl_11">Оключва се на ниво 11</string>
|
||||
<string name="no_party_message">Вие не участвате в група. За да се присъедините към група, моля, посетете уеб сайта.</string>
|
||||
<string name="forgot_pw_btn">Забравена парола</string>
|
||||
<string name="forgot_pw_tv">Забравена парола? Моля, използвайте мобилния уеб сайт.</string>
|
||||
<string name="tavern.inn.checkOut">Включете отново ежедневните си задачи</string>
|
||||
<string name="tavern.inn.rest">Пауза на ежедн.</string>
|
||||
<string name="reward.dialog.buy">Купуване</string>
|
||||
<string name="reward.dialog.dismiss">Премахване</string>
|
||||
<string name="party">Група</string>
|
||||
<string name="chat">Чат</string>
|
||||
<string name="members">Членове</string>
|
||||
<string name="habits">Навици</string>
|
||||
<string name="dailies">Ежедневни</string>
|
||||
<string name="todos">Задачи</string>
|
||||
<string name="rewards">Награди</string>
|
||||
<string name="taskform.delete.title">Сигурен/на ли сте?</string>
|
||||
<string name="taskform.delete.message">Наистина ли искате да изтриете това?</string>
|
||||
<string name="yes">Да</string>
|
||||
<string name="no">Не</string>
|
||||
<string name="quest">Мисия</string>
|
||||
<string name="avatar_body">Тяло</string>
|
||||
<string name="avatar_hair">Коса</string>
|
||||
<string name="avatar_shirt">Риза</string>
|
||||
<string name="avatar_skin">Кожа</string>
|
||||
<string name="avatar_ears">Животински уши</string>
|
||||
<string name="avatar_base">Основа</string>
|
||||
<string name="avatar_color">Цвят</string>
|
||||
<string name="avatar_beard">Брада</string>
|
||||
<string name="avatar_mustache">Мустаци</string>
|
||||
<string name="avatar_flower">Цвете</string>
|
||||
<string name="avatar_bangs">Бретон</string>
|
||||
<string name="avatar_nothing">Няма нищо</string>
|
||||
<string name="avatar_size">Размер</string>
|
||||
<string name="avatar_size_slim">Слаб</string>
|
||||
<string name="avatar_size_broad">Широк</string>
|
||||
<string name="avatar_background">Фон</string>
|
||||
<string name="purchase_customization">Купуване на персонализация</string>
|
||||
<string name="purchase_set_button" formatted="false">Отключване на комплекта за %d диамант(а)</string>
|
||||
<string name="purchase_button">Купуване</string>
|
||||
<string name="purchase_set_title" formatted="false">Купуване на комплекта %s</string>
|
||||
<string name="due_date">Крайна дата</string>
|
||||
<string name="quest.accept">Приемане</string>
|
||||
<string name="quest.reject">Отказване</string>
|
||||
<string name="quest.begin">Започване на мисия</string>
|
||||
<string name="quest.cancel">Отказване на поканата</string>
|
||||
<string name="quest.abort">Прекратяване на мисията</string>
|
||||
<string name="quest.leave">Напускане на мисията</string>
|
||||
<string name="quest.pending">В очакване</string>
|
||||
<string name="quest.accepted">Приета</string>
|
||||
<string name="quest.rejected">Отказана</string>
|
||||
<string name="quest.participants">Участници</string>
|
||||
<string name="version_info" formatted="false">Версия %s (%d)</string>
|
||||
<string name="sidebar_help">Помощ и ЧЗВ</string>
|
||||
<string name="complete_tutorial">Разбрано!</string>
|
||||
<string name="dismiss_tutorial">Напомнете ми отново</string>
|
||||
<string name="intro_1_title">Добре дошли в Хабитика</string>
|
||||
<string name="intro_1_description">Над 1 100 000 хора се забавляват, докато вършат нещата си. Присъединете се към тях! Създайте си герой и следете задачите от истинския си живот.</string>
|
||||
<string name="intro_2_title">Напредък в играта = напредък в живота</string>
|
||||
<string name="intro_2_description">Отключвайте функционалностите на играта като изпълнявате задачите в истинския си живот. Печелете екипировка, любимци и още, като награда за постигането на целите си!</string>
|
||||
<string name="intro_3_title">Общност и битки с чудовища</string>
|
||||
<string name="intro_3_description">Приятелите Ви могат да Ви помогнат да постигнете целите си. Подкрепяйте се взаимно в живота и битките, за да израснете заедно!</string>
|
||||
<string name="intro_finish_button">Започване</string>
|
||||
<string name="previous_button">Назад</string>
|
||||
<string name="next_button">Напред</string>
|
||||
<string name="skip_button">Пропускане</string>
|
||||
<string name="setup_welcome_description">Добре дошли в Хабитика, където напредването в играта ще подобри истинския Ви живот! Докато изпълнявате реалните си цели, ще отключвате екипировка, любимци, мисии и още.</string>
|
||||
<string name="setup_welcome_title">Добре дошли</string>
|
||||
<string name="avatar_setup_description">Първо, ще Ви трябва герой, който да Ви представлява в играта! Нещата, които вършите в истинския си живот, ще се отразяват на здравето, нивото и златото на героя Ви.</string>
|
||||
<string name="task_setup_description">Чудесно! А сега да създадем няколко задачи, за да започнете да печелите опит и злато.
|
||||
|
||||
Кои области от живота си искате да подобрите?</string>
|
||||
<string name="setup_group_work">Работа</string>
|
||||
<string name="setup_group_exercise">Упражнения</string>
|
||||
<string name="setup_group_heathWellness">Здравословно състояние</string>
|
||||
<string name="setup_group_school">Училище</string>
|
||||
<string name="setup_group_teams">Екипи</string>
|
||||
<string name="setup_group_chores">Домакинска работа</string>
|
||||
<string name="setup_group_creativity">Изобретателност</string>
|
||||
<string name="setup_task_work_1">Обработка на е-поща</string>
|
||||
<string name="setup_task_work_2">Най-важната задача</string>
|
||||
<string name="setup_task_work_3">Работен проект</string>
|
||||
<string name="setup_task_exercise_1">10 мин аеробни упражнения</string>
|
||||
<string name="setup_task_exercise_2">Разтягане</string>
|
||||
<string name="setup_task_exercise_3">Да организирам тренировките си</string>
|
||||
<string name="setup_task_healthWellness_1">Да ям полезна/вредна храна</string>
|
||||
<string name="setup_task_healthWellness_2">Да изчистя зъбите си с конец</string>
|
||||
<string name="setup_task_healthWellness_3">Да се запиша за преглед</string>
|
||||
<string name="setup_task_school_1">Учене/отлагане</string>
|
||||
<string name="setup_task_school_2">Да напиша домашното си</string>
|
||||
<string name="setup_task_school_3">Да завърша проекта за училище</string>
|
||||
<string name="setup_task_teams_1">Да проверя какво прави екипът</string>
|
||||
<string name="setup_task_teams_2">Да уведомя екипа за напредъка си</string>
|
||||
<string name="setup_task_teams_3">Да завърша екипния проект</string>
|
||||
<string name="setup_task_chores_1">10 минути чистене</string>
|
||||
<string name="setup_task_chores_2">Да измия чиниите</string>
|
||||
<string name="setup_task_chores_3">Да подредя килера</string>
|
||||
<string name="setup_task_creativity_1">Да се уча от майстор в занаята</string>
|
||||
<string name="setup_task_creativity_2">Да работя по проекта си</string>
|
||||
<string name="setup_task_creativity_3">Да завърша проекта си</string>
|
||||
<string name="gem.purchase.support">Искате ли да помогнете на Хабитика да продължи да съществува? Можете да подкрепите разработчиците като купите диаманти!\n\nС диамантите можете да си купувате забавни неща за профила си, като: \n\n — Интересни костюми за героя си;\n — Страхотни фонове;\n — Забавни мисии, от които ще получите яйца за любимци;\n — Възможността да променяте класа си преди да достигнете ниво 100.\n\nБлагодарим Ви за това, че помагате на Хабитика да се развива. Подкрепата Ви означава много за нас!</string>
|
||||
<string name="my_guilds">Моите гилдии</string>
|
||||
<string name="public_guilds">Обществени гилдии</string>
|
||||
<string name="guild">Гилдия</string>
|
||||
<string name="leave">Напускане</string>
|
||||
<string name="join">Присъединяване</string>
|
||||
<string name="leader">Водач</string>
|
||||
<string name="gems">Диаманти</string>
|
||||
<string name="copy_as_todo">Копиране като задача</string>
|
||||
<string name="send_pm">Изпращане на ЛС</string>
|
||||
<string name="flag">Докладване</string>
|
||||
<string name="delete">Изтриване</string>
|
||||
<string name="name">Име</string>
|
||||
<string name="description">Описание</string>
|
||||
<string name="add_tag">Добавяне на етикет</string>
|
||||
<string name="privacy">Поверителност</string>
|
||||
<string name="write_message">Напишете съобщение</string>
|
||||
<string name="post">Изпр.</string>
|
||||
<string name="todo_due" formatted="false">Срок: %s</string>
|
||||
<string name="daily_streak" formatted="false">текуща серия: %d</string>
|
||||
<string name="todo_has_duedate">Задачата има краен срок</string>
|
||||
<string name="battle_gear">Бойно снаряжение</string>
|
||||
<string name="costume">Костюм</string>
|
||||
<string name="outfit_head">Глава</string>
|
||||
<string name="outfit_headAccessory">Аксесоар за глава</string>
|
||||
<string name="outfit_eyewear">Предмет за очи</string>
|
||||
<string name="outfit_armor">Броня</string>
|
||||
<string name="outfit_back">Гръб</string>
|
||||
<string name="outfit_body">Тяло</string>
|
||||
<string name="outfit_shield">Щит</string>
|
||||
<string name="outfit_weapon">Оръжие</string>
|
||||
<string name="wear_costume">Костюм</string>
|
||||
<string name="equipped">Екипирано</string>
|
||||
<string name="quest_cancel_message">Наистина ли искате да прекратите мисията? Всички приети покани ще бъдат загубени. Притежателят на мисията ще си запази свитъка ѝ.</string>
|
||||
<string name="quest.invitation">Покана за мисия</string>
|
||||
<string name="quest_begin_message">Наистина ли искате да започнете мисията? След като мисията започне, никой повече няма да може да се присъедини към нея.</string>
|
||||
<string name="quest.invitation.text">Получихте покана за участие в мисия!</string>
|
||||
<string name="ago_1day">Преди 1 ден</string>
|
||||
<string name="ago_days" formatted="false">Преди %d дни</string>
|
||||
<string name="ago_1Minute">Преди 1 минута</string>
|
||||
<string name="ago_minutes" formatted="false">Преди %d минути</string>
|
||||
<string name="ago_hours" formatted="false">Преди %d часа</string>
|
||||
<string name="ago_1hour">Преди 1 час</string>
|
||||
<string name="today">Днес</string>
|
||||
<string name="sidebar_items">Предмети</string>
|
||||
<string name="eggs">Яйца</string>
|
||||
<string name="hatching_potions">Излюпващи отвари</string>
|
||||
<string name="food">Храна</string>
|
||||
<string name="quests">Мисии</string>
|
||||
<string name="pets">Любимци</string>
|
||||
<string name="mounts">Превози</string>
|
||||
<string name="armoireEquipment" formatted="false">Намерихте рядък предмет в гардероба: %s! Страхотно!</string>
|
||||
<string name="armoireFood" formatted="false">Тършувате из гардероба и намирате %1$s %2$s. Какво ли прави това там?</string>
|
||||
<string name="armoireExp">Сборвате се с гардероба и получавате опит. Така му се пада!</string>
|
||||
<string name="armoireNotesFull" formatted="false">Отворете гардероба, за да получите случайно избрана специална екипировка, опит или храна! Оставащи предмети: %d</string>
|
||||
<string name="armoireLastItem">Намерихте последния рядък предмет за екипиране в омагьосания гардероб.</string>
|
||||
<string name="armoireNotesEmpty">В гардероба ще се появяват нови предмети през първата седмица на всеки месец. До тогава продължавайте да щракате за опит и храна!</string>
|
||||
<string name="sell" formatted="false">Продаване (%s злато)</string>
|
||||
<string name="hatch_with_potion">Излюпване с отвара</string>
|
||||
<string name="feed_to_pet">Даване на любимец</string>
|
||||
<string name="hatch_egg">Излюпване с яйце</string>
|
||||
<string name="invite_party">Поканване на групата</string>
|
||||
<string name="dialog_feeding" formatted="false">Хранене на %1$s %2$s с:</string>
|
||||
<string name="use_animal">Използване</string>
|
||||
<string name="feed">Хранене</string>
|
||||
<string name="hatch_with" formatted="false">Излюпване на любимец с %s</string>
|
||||
<string name="hatched_pet_title" formatted="false">Вие излюпихте %1$s %2$s!</string>
|
||||
<string name="close">Затваряне</string>
|
||||
<string name="share">Споделяне</string>
|
||||
<string name="notification_pet_fed" formatted="false">Вие нахранихте своя(та/то) %1$s %2$s!</string>
|
||||
<string name="notification_purchase" formatted="false">%s беше закупен(а/о)</string>
|
||||
<string name="sectionpets">Обикновени любимци</string>
|
||||
<string name="sectionpremiumPets">Любимци от магически отвари</string>
|
||||
<string name="sectionquestPets">Любимци от мисии</string>
|
||||
<string name="sectionspecialPets">Редки любимци</string>
|
||||
<string name="sectionmounts">Обикновени превози</string>
|
||||
<string name="sectionpremiumMounts">Превози от магически отвари</string>
|
||||
<string name="sectionquestMounts">Превози от мисии</string>
|
||||
<string name="sectionspecialMounts">Редки превози</string>
|
||||
<string name="world_quest">Световна мисия</string>
|
||||
<string name="inn_description">Починете в странноприемницата, за да не могат да Ви наранят неизпълнените Ви ежедневни задачи! (Забележка: това не Ви защитава от получаването на щети от главатари.)</string>
|
||||
<string name="empty_items" formatted="false">Нямате %s</string>
|
||||
<string name="user_level" formatted="false">Ниво %s</string>
|
||||
<string name="user_level_with_class" formatted="false">Ниво %1$s - %2$s</string>
|
||||
<string name="warrior">Воин</string>
|
||||
<string name="rogue">Мошеник</string>
|
||||
<string name="mage">Магьосник</string>
|
||||
<string name="healer">Лечител</string>
|
||||
<string name="warrior_description">Воините нанасят повече и по-силни „критични удари“, които на случаен принцип дават злато, опит и шанс за падане на предмет при изпълнение на задача. Те също така нанасят сериозни щети на чудовищата-главатари. Играйте като воин, ако Ви мотивират изненадващите награди, или ако искате да раздавате правосъдие в мисиите с главатари.</string>
|
||||
<string name="mage_description">Магьосниците се учат лесно, тъй като придобиват опит и нива по-бързо от останалите класове. Те имат много мана за специалните си умения. Играйте като магьосник, ако обичате тактическите страни на навиците, или ако се мотивирате от вдигане на нива и отключване на специални функционалности!</string>
|
||||
<string name="rogue_description">Мошениците обичат да трупат богатства, печелят повече злато повече от останалите и са майстори в намирането на случайни предмети. Отличителното им умение „Невидимост“ им позволява да избегнат последствията от пропуснати ежедневни задачи. Играйте като мошеник, ако Ви мотивират наградите и постиженията, и обичате плячката и значките!</string>
|
||||
<string name="healer_description">Лечителите трудно могат да бъдат наранени, и разпростират защитата си върху останалите. Пропуснатите ежедневни задачи и лошите навици не ги смущават толкова много; те винаги могат да възстановят здравето си след провал. Играйте като лечител, ако обичате да помагате на останалите в групата си, или ако искате да изиграете смъртта чрез усърдна работа!</string>
|
||||
<string name="select_class">Изберете клас</string>
|
||||
<string name="opt_out_class">Отказване</string>
|
||||
<string name="opt_out_description">Не Ви се занимава с класове? Искате да изберете по-късно? Откажете се от тях — ще бъдете воин без специални умения. Можете да прочетете относно класовата система по-късно в уикито, както и да включите класовете когато пожелаете.</string>
|
||||
<string name="class_confirmation" formatted="false">Наистина ли искате да бъдете %s?</string>
|
||||
<string name="choose_class">Избиране на класа</string>
|
||||
<string name="dialog_go_back">Назад</string>
|
||||
<string name="opt_out_confirmation">Наистина ли искате да се откажете?</string>
|
||||
<string name="change_class">Промяна на класа</string>
|
||||
<string name="change_class_description">Променете класа си и възстановете атрибутните си точки за 3 диаманта. Можете да разпределите атрибутните си точки през уеб сайта</string>
|
||||
<string name="enable_class">Включване на класовата система</string>
|
||||
<string name="changing_class_progress">Промяна на класа</string>
|
||||
<string name="by_email">По е-поща</string>
|
||||
<string name="invite_existing_users">Поканете съществуващи потребители</string>
|
||||
<string name="send">Изпращане</string>
|
||||
<string name="invite">Поканете приятели</string>
|
||||
<string name="invite_id_description">Ако имате приятели, които вече използват Хабитика, поканете ги чрез потребителски идентификатор тук.</string>
|
||||
<string name="invite_email_description">Ако приятел се присъедини към Хабитика през Вашето е-писмо, той автоматично ще бъде поканен в групата Ви!</string>
|
||||
<string name="add_invites">Добавяне на покани</string>
|
||||
<string name="user_id">Потребителски ид.</string>
|
||||
<string name="email">Е-поща</string>
|
||||
<string name="invite_users">Поканване в групата</string>
|
||||
<string name="share_using">Споделяне чрез</string>
|
||||
<string name="share_levelup" formatted="false">Достигнах ниво %s в Хабитика, като подобрих навиците си в истинския живот!</string>
|
||||
<string name="share_hatched" formatted="false">Току-що излюпих любимец — %1$s %2$s в Хабитика, като изпълнявах задачите си в истинския живот!</string>
|
||||
<string name="share_raised" formatted="false">Току-що се сдобих с превоз — %1$s %2$s в Хабитика, като изпълнявах задачите си в истинския живот!</string>
|
||||
<string name="open_in_store">Отваряне в магазина</string>
|
||||
<string name="change_class_confirmation">Наистина ли искате да промените класа си? Това ще Ви струва 3 диаманта.</string>
|
||||
<string name="leaderMessage" formatted="false">Съобщение от %1$s</string>
|
||||
<string name="confirm">Потвърждаване</string>
|
||||
<string name="market">Пазар</string>
|
||||
<string name="timeTravelers">Пътешественици във времето</string>
|
||||
<string name="seasonalShop">Сезонен магазин</string>
|
||||
<string name="empty_inbox">Нямате входящи съобщения. Можете да изпратите ново съобщение на потребител от екрана с неговите публични съобщения в чата!</string>
|
||||
<string name="party_invite">Отключете, като поканите приятели</string>
|
||||
<string name="no_gold">Нямате достатъчно злато</string>
|
||||
<string name="no_potion">Няма нужда да купувате лечебна отвара</string>
|
||||
<string name="successful_purchase" formatted="false">Закупено успешно: %1$s</string>
|
||||
<string name="purchase_confirmation_title">Потвърждаване на покупката</string>
|
||||
<string name="confirm_purchase_text" formatted="false">Купуване на %1$s за %2$s %3$s</string>
|
||||
<string name="gem">диамант</string>
|
||||
<string name="hourglass">пясъчен часовник</string>
|
||||
<string name="hourglasses">пясъчни часовници</string>
|
||||
<string name="gold_singular">злато</string>
|
||||
<string name="gems_plural">злато</string>
|
||||
</resources>
|
||||
|
|
@ -16,4 +16,5 @@
|
|||
<string name="sidebar.news">Neuigkeiten</string>
|
||||
<string name="sidebar.settings">Einstellungen</string>
|
||||
<string name="sidebar.about">Über</string>
|
||||
<string name="sidebar_shops">Märkte</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@
|
|||
<string name="network_error_title">Verbindungsfehler</string>
|
||||
<string name="network_error_no_network_body">Keine Internetverbindung.</string>
|
||||
<string name="internal_error_api">Es scheint ein Problem mit dem Server zu geben. Versuch es später noch mal.</string>
|
||||
<string name="authentication_error_title">Autentifikationsfehler</string>
|
||||
<string name="authentication_error_title">Authentifikationsfehler</string>
|
||||
<string name="authentication_error_body">Ungültiger Benutzername und/oder Passwort</string>
|
||||
<string name="login_validation_error_title">Validierungsfehler</string>
|
||||
<string name="login_validation_error_fieldsmissing">Bitte fülle alle Felder aus.</string>
|
||||
|
|
@ -166,14 +166,14 @@
|
|||
<string name="intro_2_title">Spielfortschritt = Lebensfortschritt</string>
|
||||
<string name="intro_2_description">Schalte zusätzliche Spielinhalte frei, indem Du Aufgaben im echten Leben erledigst. Verdiene Dir Ausrüstung, Haustiere und mehr als Belohnung für die Erfüllung Deiner Ziele!</string>
|
||||
<string name="intro_3_title">Werde sozial und kämpfe gegen Monster</string>
|
||||
<string name="intro_3_description">Behalte Deine Ziele im Auge mit Hilfe Deiner Freunde. Unterstützt Euch gegenseitig im Leben und im Kampf während Ihr Euch gemeinsam verbessert!</string>
|
||||
<string name="intro_3_description">Behalte Deine Ziele im Auge mit Hilfe Deiner Freunde. Unterstützt Euch gegenseitig im Leben und im Kampf, während Ihr Euch gemeinsam verbessert!</string>
|
||||
<string name="intro_finish_button">Anfangen</string>
|
||||
<string name="previous_button">Zurück</string>
|
||||
<string name="next_button">Weiter</string>
|
||||
<string name="skip_button">Überspringen</string>
|
||||
<string name="setup_welcome_description">Willkommen zu Habitica! Hier bedeutet Fortschritt im Spiel gleichzeitig Fortschritt im echten Leben! Während Du Ziele im echten Leben erreichst, wirst Du Ausrüstung, Haustiere, Quests und vieles mehr freischalten.</string>
|
||||
<string name="setup_welcome_title">Willkommen</string>
|
||||
<string name="avatar_setup_description">Als erstes benötigst Du einen Avater, der Dich repräsentiert! Dinge die Du im echten Leben tust beeinflussen Deine Lebenspunkte, Dein Level und Dein Gold.</string>
|
||||
<string name="avatar_setup_description">Als erstes benötigst Du einen Avatar, der Dich repräsentiert! Dinge die Du im echten Leben tust beeinflussen Deine Lebenspunkte, Dein Level und Dein Gold.</string>
|
||||
<string name="task_setup_description">Großartig! Jetzt lass uns Deine Aufgaben anlegen, damit Du anfangen kannst Erfahrung zu sammeln und Gold zu bekommen.
|
||||
|
||||
Für den Anfang: Welche Bereiche Deines Lebens möchtest Du verbessern?</string>
|
||||
|
|
@ -330,4 +330,15 @@ Für den Anfang: Welche Bereiche Deines Lebens möchtest Du verbessern?</string>
|
|||
<string name="timeTravelers">Mysteriöse Zeitreisende</string>
|
||||
<string name="seasonalShop">Jahreszeitenmarkt</string>
|
||||
<string name="empty_inbox">Du hast keine Nachrichten in Deinem Posteingang. Du kannst einem anderen Benutzer eine neue Nachricht von deren öffentlichen Chatnachrichten aus senden!</string>
|
||||
<string name="party_invite">Durch Einladen von Freunden freischalten</string>
|
||||
<string name="no_gold">Nicht genügend Gold</string>
|
||||
<string name="no_potion">Du musst keinen Heiltrank kaufen</string>
|
||||
<string name="successful_purchase" formatted="false">%1$s gekauft</string>
|
||||
<string name="purchase_confirmation_title">Kauf bestätigen</string>
|
||||
<string name="confirm_purchase_text" formatted="false">%1$s für %2$s %3$s kaufen</string>
|
||||
<string name="gem">Edelstein</string>
|
||||
<string name="hourglass">Sanduhr</string>
|
||||
<string name="hourglasses">Sanduhren</string>
|
||||
<string name="gold_singular">Gold</string>
|
||||
<string name="gems_plural">Gold</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -16,4 +16,5 @@
|
|||
<string name="sidebar.news">Noticias</string>
|
||||
<string name="sidebar.settings">Ajustes</string>
|
||||
<string name="sidebar.about">Información</string>
|
||||
<string name="sidebar_shops">Tiendas</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -325,4 +325,9 @@ Para empezar, ¿qué aspectos de tu vida te gustaría mejorar?</string>
|
|||
<string name="open_in_store">Abrir en Play Store</string>
|
||||
<string name="change_class_confirmation">¿Seguro que quieres cambiar de clase? Te costará 3 gemas.</string>
|
||||
<string name="leaderMessage" formatted="false">Mensaje de %1$s</string>
|
||||
<string name="confirm">Confirmar</string>
|
||||
<string name="market">Mercado</string>
|
||||
<string name="timeTravelers">Viajeros del tiempo</string>
|
||||
<string name="seasonalShop">Tienda estacional</string>
|
||||
<string name="empty_inbox">No tienes ningún mensaje en la bandeja de entrada. Puedes enviar un mensaje a un usuario desde los mensajes de chat públicos que hayan enviado.</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -329,5 +329,16 @@ Pour commencer, quels aspects de votre vie souhaitez-vous améliorer ?</string>
|
|||
<string name="market">Marché</string>
|
||||
<string name="timeTravelers">Voyageurs temporels</string>
|
||||
<string name="seasonalShop">Boutique saisonnière</string>
|
||||
<string name="empty_inbox">Vous n\'avez pas de message dans la boite de réception. Vous pouvez envoyer un nouveau message à partir des discussions publiques de chaque personne.</string>
|
||||
<string name="empty_inbox">Vous n\'avez pas de message dans votre boîte de réception. Vous pouvez envoyer un nouveau message à partir des messages de discussion publics de chaque personne.</string>
|
||||
<string name="party_invite">Débloquer en invitant des ami•e•s</string>
|
||||
<string name="no_gold">Pas assez d\'or</string>
|
||||
<string name="no_potion">Vous n\'avez pas besoin d\'acheter une potion de santé</string>
|
||||
<string name="successful_purchase" formatted="false">%1$s acheté avec succès</string>
|
||||
<string name="purchase_confirmation_title">Confirmer l\'achat</string>
|
||||
<string name="confirm_purchase_text" formatted="false">Acheter %1$s for %2$s %3$s</string>
|
||||
<string name="gem">gemme</string>
|
||||
<string name="hourglass">sablier</string>
|
||||
<string name="hourglasses">sabliers</string>
|
||||
<string name="gold_singular">or</string>
|
||||
<string name="gems_plural">or</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -16,4 +16,5 @@
|
|||
<string name="sidebar.news">お知らせ</string>
|
||||
<string name="sidebar.settings">設定</string>
|
||||
<string name="sidebar.about">Habitica について</string>
|
||||
<string name="sidebar_shops">ショップ</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -326,4 +326,20 @@
|
|||
<string name="open_in_store">Play ストアで開く</string>
|
||||
<string name="change_class_confirmation">クラスを変更します。いいですか? 3 ジェムかかります。</string>
|
||||
<string name="leaderMessage" formatted="false">%1$s からのメッセージ</string>
|
||||
<string name="confirm">確認</string>
|
||||
<string name="market">市場</string>
|
||||
<string name="timeTravelers">タイムトラベラー</string>
|
||||
<string name="seasonalShop">期間限定ショップ</string>
|
||||
<string name="empty_inbox">受信箱にメッセージがありません。Habitica ユーザーあてにメッセージを送ることができます。公開チャットに投稿しているユーザーにメッセージを送ってみてはどうですか?</string>
|
||||
<string name="party_invite">友達を招待するとアンロック</string>
|
||||
<string name="no_gold">ゴールドが足りません</string>
|
||||
<string name="no_potion">体力回復の薬を買う必要がありません</string>
|
||||
<string name="successful_purchase" formatted="false">%1$s を買いました</string>
|
||||
<string name="purchase_confirmation_title">購入の確認</string>
|
||||
<string name="confirm_purchase_text" formatted="false">%2$s %3$s で %1$s を買う</string>
|
||||
<string name="gem">ジェム</string>
|
||||
<string name="hourglass">砂時計</string>
|
||||
<string name="hourglasses">砂時計</string>
|
||||
<string name="gold_singular">ゴールド</string>
|
||||
<string name="gems_plural">ゴールド</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -330,4 +330,15 @@ Om te beginnen, welke delen van je leven wil je verbeteren?</string>
|
|||
<string name="timeTravelers">Tijd Reizigers</string>
|
||||
<string name="seasonalShop">Seizoenswinkel</string>
|
||||
<string name="empty_inbox">Je hebt geen Inbox berichten. Je kan een gebruiker een nieuw bericht sturen vanuit hun publieke chat berichten.</string>
|
||||
<string name="party_invite">Ontgrendel door vrienden uit te nodigen</string>
|
||||
<string name="no_gold">Niet genoeg goud</string>
|
||||
<string name="no_potion">Je hoeft geen gezondheidsdrankje te kopen</string>
|
||||
<string name="successful_purchase" formatted="false">%1$s succesvol gekocht</string>
|
||||
<string name="purchase_confirmation_title">Bevestig aankoop</string>
|
||||
<string name="confirm_purchase_text" formatted="false">Koop %1$s voor %2$s %3$s</string>
|
||||
<string name="gem">edelsteen</string>
|
||||
<string name="hourglass">zandloper</string>
|
||||
<string name="hourglasses">zandlopers</string>
|
||||
<string name="gold_singular">goud</string>
|
||||
<string name="gems_plural">goud</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -326,4 +326,12 @@ Para começar, quais partes da sua vida você quer melhorar?</string>
|
|||
<string name="open_in_store">Abra na Play Store</string>
|
||||
<string name="change_class_confirmation">Você tem certeza que quer mudar sua classe? Isso irá custar 3 gemas.</string>
|
||||
<string name="leaderMessage" formatted="false">Mensagem de %1$s</string>
|
||||
<string name="confirm">Confirmar</string>
|
||||
<string name="market">Mercado</string>
|
||||
<string name="no_potion">Você não precisa comprar uma poção de vida</string>
|
||||
<string name="successful_purchase" formatted="false">%1$s comprado com sucesso</string>
|
||||
<string name="purchase_confirmation_title">Confirmar compra</string>
|
||||
<string name="gem">gema</string>
|
||||
<string name="gold_singular">ouro</string>
|
||||
<string name="gems_plural">ouro</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -16,4 +16,5 @@
|
|||
<string name="sidebar.news">新聞</string>
|
||||
<string name="sidebar.settings">設定</string>
|
||||
<string name="sidebar.about">關於</string>
|
||||
<string name="sidebar_shops">商店</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -113,7 +113,7 @@
|
|||
<string name="tavern.inn.checkOut">重啟每日任務</string>
|
||||
<string name="tavern.inn.rest">暫停每日任務</string>
|
||||
<string name="reward.dialog.buy">購買</string>
|
||||
<string name="reward.dialog.dismiss">解散</string>
|
||||
<string name="reward.dialog.dismiss">取消</string>
|
||||
<string name="party">隊伍</string>
|
||||
<string name="chat">聊天</string>
|
||||
<string name="members">成員</string>
|
||||
|
|
@ -322,5 +322,12 @@
|
|||
<string name="share_levelup" formatted="false">我在Habitica中通過改善我現實生活中的習慣到達了%s級!</string>
|
||||
<string name="share_hatched" formatted="false">我剛剛在Habitica中通完成我現實生活中的任務孵化了一隻寵物%1$s %2$s!</string>
|
||||
<string name="share_raised" formatted="false">我剛剛在Habitica中通完成我現實生活中的任務得到了一匹坐騎%1$s %2$s!</string>
|
||||
<string name="open_in_store">開啟Play sotre</string>
|
||||
<string name="change_class_confirmation">你確定要變更職業嗎?這會花費3寶石。</string>
|
||||
<string name="leaderMessage" formatted="false">訊息來自%1$s</string>
|
||||
<string name="confirm">確認</string>
|
||||
<string name="market">市集</string>
|
||||
<string name="timeTravelers">時光旅人</string>
|
||||
<string name="seasonalShop">季節限定商店</string>
|
||||
<string name="empty_inbox">你的收件匣裡面沒有任何信息。你可以利用聊天去傳送訊息給大家</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -16,4 +16,5 @@
|
|||
<string name="sidebar.news">新闻</string>
|
||||
<string name="sidebar.settings">设置</string>
|
||||
<string name="sidebar.about">关于</string>
|
||||
<string name="sidebar_shops">商店</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -325,4 +325,20 @@
|
|||
<string name="open_in_store">在应用商店开放</string>
|
||||
<string name="change_class_confirmation">你确定想要转变职业吗?这将花费3颗宝石。</string>
|
||||
<string name="leaderMessage" formatted="false">从%1$s来的消息</string>
|
||||
<string name="confirm">确认</string>
|
||||
<string name="market">市场</string>
|
||||
<string name="timeTravelers">时光旅行</string>
|
||||
<string name="seasonalShop">四季商店</string>
|
||||
<string name="empty_inbox">收件箱里没有消息。您可以在用户的公共聊天窗口中给他发送新消息!</string>
|
||||
<string name="party_invite">通过邀请朋友来解锁</string>
|
||||
<string name="no_gold">没有足够的金币</string>
|
||||
<string name="no_potion">你不需要购买生命药水</string>
|
||||
<string name="successful_purchase" formatted="false">已购买 %1$s</string>
|
||||
<string name="purchase_confirmation_title">确认购买</string>
|
||||
<string name="confirm_purchase_text" formatted="false">为 %2$s %3$s 购买 %1$s</string>
|
||||
<string name="gem">宝石</string>
|
||||
<string name="hourglass">沙漏</string>
|
||||
<string name="hourglasses">沙漏</string>
|
||||
<string name="gold_singular">金币</string>
|
||||
<string name="gems_plural">金币</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
@ -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>
|
||||
|
|
@ -363,4 +374,6 @@ To start, which parts of your life do you want to improve?</string>
|
|||
<string name="hourglasses">hourglasses</string>
|
||||
<string name="gold_singular">gold</string>
|
||||
<string name="gems_plural">gold</string>
|
||||
<string name="chat_message_copied">Message copied to Clipboard</string>
|
||||
<string name="copy_chat_message">Copy to clipboard</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
@ -163,17 +163,22 @@ public class APIHelper implements Action1<Throwable> {
|
|||
logging.setLevel(HttpLoggingInterceptor.Level.BODY);
|
||||
}
|
||||
|
||||
String userAgent = System.getProperty("http.agent");
|
||||
|
||||
OkHttpClient client = new OkHttpClient.Builder()
|
||||
.addInterceptor(remove_data_interceptor)
|
||||
.addInterceptor(logging)
|
||||
.addNetworkInterceptor(chain -> {
|
||||
Request original = chain.request();
|
||||
if (this.hostConfig.getUser() != null) {
|
||||
Request request = original.newBuilder()
|
||||
Request.Builder builder = original.newBuilder()
|
||||
.header("x-api-key", this.hostConfig.getApi())
|
||||
.header("x-api-user", this.hostConfig.getUser())
|
||||
.header("x-client", "habitica-android")
|
||||
.method(original.method(), original.body())
|
||||
.header("x-client", "habitica-android");
|
||||
if (userAgent != null) {
|
||||
builder = builder.header("user-agent", userAgent);
|
||||
}
|
||||
Request request = builder.method(original.method(), original.body())
|
||||
.build();
|
||||
return chain.proceed(request);
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ import android.app.Activity;
|
|||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.database.DatabaseErrorHandler;
|
||||
|
|
@ -130,7 +131,11 @@ public class HabiticaApplication extends MultiDexApplication {
|
|||
setupCrashlytics();
|
||||
createBillingAndCheckout();
|
||||
registerActivityLifecycleCallbacks();
|
||||
Amplitude.getInstance().initialize(this, getString(R.string.amplitude_app_id)).enableForegroundTracking(this);
|
||||
|
||||
if (!BuildConfig.DEBUG) {
|
||||
Amplitude.getInstance().initialize(this, getString(R.string.amplitude_app_id)).enableForegroundTracking(this);
|
||||
}
|
||||
|
||||
Fresco.initialize(this);
|
||||
checkIfNewVersion();
|
||||
}
|
||||
|
|
@ -180,7 +185,19 @@ public class HabiticaApplication extends MultiDexApplication {
|
|||
}
|
||||
|
||||
private void setupFacebookSdk() {
|
||||
FacebookSdk.sdkInitialize(getApplicationContext());
|
||||
String fbApiKey = null;
|
||||
try {
|
||||
ApplicationInfo ai = getPackageManager().getApplicationInfo(getPackageName(), PackageManager.GET_META_DATA);
|
||||
Bundle bundle = ai.metaData;
|
||||
fbApiKey = bundle.getString(FacebookSdk.APPLICATION_ID_PROPERTY);
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
Log.e("FB Error", "Failed to load meta-data, NameNotFound: " + e.getMessage());
|
||||
} catch (NullPointerException e) {
|
||||
Log.e("FB Error", "Failed to load meta-data, NullPointer: " + e.getMessage());
|
||||
}
|
||||
if (fbApiKey != null) {
|
||||
FacebookSdk.sdkInitialize(getApplicationContext());
|
||||
}
|
||||
}
|
||||
|
||||
private void setupCrashlytics() {
|
||||
|
|
|
|||
|
|
@ -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.FullProfileActivity;
|
||||
|
|
@ -158,5 +160,9 @@ public interface AppComponent {
|
|||
|
||||
void inject(ShopFragment shopFragment);
|
||||
|
||||
void inject(PushNotificationManager pushNotificationManager);
|
||||
|
||||
void inject(LocalNotificationActionReceiver localNotificationActionReceiver);
|
||||
|
||||
void inject(FullProfileActivity fullProfileActivity);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,12 @@
|
|||
package com.habitrpg.android.habitica.events.commands;
|
||||
|
||||
import com.magicmicky.habitrpgwrapper.lib.models.ChatMessage;
|
||||
|
||||
/**
|
||||
* Created by jjbillings on 7/27/16.
|
||||
*/
|
||||
public class CopyChatMessageCommand extends ChatMessageCommandBase {
|
||||
public CopyChatMessageCommand(String groupId, ChatMessage chatMessage) {
|
||||
super(groupId, chatMessage);
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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 -> {});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
@ -138,6 +139,7 @@ import java.util.concurrent.TimeUnit;
|
|||
import javax.inject.Inject;
|
||||
|
||||
import butterknife.BindView;
|
||||
import retrofit2.adapter.rxjava.HttpException;
|
||||
import rx.Observable;
|
||||
import rx.functions.Action1;
|
||||
|
||||
|
|
@ -205,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;
|
||||
|
|
@ -221,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);
|
||||
|
|
@ -348,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(() -> {
|
||||
|
|
@ -868,26 +875,38 @@ public class MainActivity extends BaseActivity implements Action1<Throwable>, Ha
|
|||
|
||||
@Subscribe
|
||||
public void onEvent(final BuyGemItemCommand event) {
|
||||
Observable<Void> observable;
|
||||
if (event.shopIdentifier.equals(Shop.TIME_TRAVELERS_SHOP)) {
|
||||
if (event.item.purchaseType.equals("gear")) {
|
||||
observable = apiHelper.apiService.purchaseMysterySet(event.item.categoryIdentifier);
|
||||
if (event.item.canBuy(user) || !event.item.getCurrency().equals("gems")) {
|
||||
Observable<Void> observable;
|
||||
if (event.shopIdentifier.equals(Shop.TIME_TRAVELERS_SHOP)) {
|
||||
if (event.item.purchaseType.equals("gear")) {
|
||||
observable = apiHelper.apiService.purchaseMysterySet(event.item.categoryIdentifier);
|
||||
} else {
|
||||
observable = apiHelper.apiService.purchaseHourglassItem(event.item.purchaseType, event.item.key);
|
||||
}
|
||||
} else if (event.item.purchaseType.equals("quests") && event.item.getCurrency().equals("gold")) {
|
||||
observable = apiHelper.apiService.purchaseQuest(event.item.key);
|
||||
} else {
|
||||
observable = apiHelper.apiService.purchaseHourglassItem(event.item.purchaseType, event.item.key);
|
||||
observable = apiHelper.apiService.purchaseItem(event.item.purchaseType, event.item.key);
|
||||
}
|
||||
observable
|
||||
.compose(apiHelper.configureApiCallObserver())
|
||||
.doOnNext(aVoid -> {
|
||||
showSnackbar(this, floatingMenuWrapper, getString(R.string.successful_purchase, event.item.text), SnackbarDisplayType.NORMAL);
|
||||
})
|
||||
.subscribe(buyResponse -> {
|
||||
apiHelper.retrieveUser(false)
|
||||
.compose(apiHelper.configureApiCallObserver())
|
||||
.subscribe(new HabitRPGUserCallback(this), throwable -> {
|
||||
});
|
||||
}, throwable -> {
|
||||
HttpException error = (HttpException) throwable;
|
||||
if (error.code() == 401 && event.item.getCurrency().equals("gems")) {
|
||||
openGemPurchaseFragment(null);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
observable = apiHelper.apiService.purchaseItem(event.item.purchaseType, event.item.key);
|
||||
openGemPurchaseFragment(null);
|
||||
}
|
||||
observable
|
||||
.compose(apiHelper.configureApiCallObserver())
|
||||
.doOnNext(aVoid -> {
|
||||
showSnackbar(this, floatingMenuWrapper, getString(R.string.successful_purchase, event.item.text), SnackbarDisplayType.NORMAL);
|
||||
})
|
||||
.subscribe(buyResponse -> {
|
||||
apiHelper.retrieveUser(false)
|
||||
.compose(apiHelper.configureApiCallObserver())
|
||||
.subscribe(new HabitRPGUserCallback(this), throwable -> {});
|
||||
}, throwable -> {});
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
|
|
@ -978,7 +997,7 @@ public class MainActivity extends BaseActivity implements Action1<Throwable>, Ha
|
|||
}
|
||||
|
||||
@Subscribe
|
||||
public void onEvent(OpenGemPurchaseFragmentCommand cmd) {
|
||||
public void openGemPurchaseFragment(OpenGemPurchaseFragmentCommand cmd) {
|
||||
drawer.setSelection(MainDrawerBuilder.SIDEBAR_PURCHASE);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -162,6 +162,10 @@ public class ShopRecyclerAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
|
|||
});
|
||||
}
|
||||
|
||||
private void canBuy() {
|
||||
|
||||
}
|
||||
|
||||
private void buyItem() {
|
||||
BuyGemItemCommand command = new BuyGemItemCommand();
|
||||
command.shopIdentifier = shopIdentifier;
|
||||
|
|
@ -171,6 +175,7 @@ public class ShopRecyclerAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
|
|||
|
||||
public void bind(ShopItem item) {
|
||||
this.item = item;
|
||||
buyButton.setVisibility(View.VISIBLE);
|
||||
titleView.setText(item.getText());
|
||||
descriptionView.setText(Html.fromHtml(item.getNotes()));
|
||||
|
||||
|
|
@ -178,15 +183,12 @@ public class ShopRecyclerAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
|
|||
|
||||
if (item.getUnlockCondition() == null) {
|
||||
buyButton.setText(item.getValue().toString());
|
||||
switch (item.getCurrency()) {
|
||||
case "gold":
|
||||
buyButton.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_header_gold, 0, 0, 0);
|
||||
break;
|
||||
case "gems":
|
||||
buyButton.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_header_gem, 0, 0, 0);
|
||||
break;
|
||||
default:
|
||||
buyButton.setVisibility(View.GONE);
|
||||
if (item.getCurrency().equals("gold")) {
|
||||
buyButton.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_header_gold, 0, 0, 0);
|
||||
} else if (item.getCurrency().equals("gems")) {
|
||||
buyButton.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_header_gem, 0, 0, 0);
|
||||
} else {
|
||||
buyButton.setVisibility(View.GONE);
|
||||
}
|
||||
unlockView.setVisibility(View.GONE);
|
||||
} else {
|
||||
|
|
@ -194,6 +196,10 @@ public class ShopRecyclerAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
|
|||
unlockView.setVisibility(View.VISIBLE);
|
||||
unlockView.setText(item.unlockCondition.readableUnlockConditionId());
|
||||
}
|
||||
|
||||
if (item.getLocked()) {
|
||||
buyButton.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package com.habitrpg.android.habitica.ui.adapter.social;
|
|||
import com.habitrpg.android.habitica.HabiticaApplication;
|
||||
import com.habitrpg.android.habitica.R;
|
||||
import com.habitrpg.android.habitica.events.commands.CopyChatAsTodoCommand;
|
||||
import com.habitrpg.android.habitica.events.commands.CopyChatMessageCommand;
|
||||
import com.habitrpg.android.habitica.events.commands.DeleteChatMessageCommand;
|
||||
import com.habitrpg.android.habitica.events.commands.FlagChatMessageCommand;
|
||||
import com.habitrpg.android.habitica.events.commands.OpenNewPMActivityCommand;
|
||||
|
|
@ -446,6 +447,12 @@ public class ChatRecyclerViewAdapter extends RecyclerView.Adapter<ChatRecyclerVi
|
|||
|
||||
break;
|
||||
}
|
||||
|
||||
case R.id.menu_chat_copy: {
|
||||
EventBus.getDefault().post(new CopyChatMessageCommand(groupId, currentMsg));
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -3,11 +3,8 @@ package com.habitrpg.android.habitica.ui.fragments.inventory.shops;
|
|||
import com.habitrpg.android.habitica.APIHelper;
|
||||
import com.habitrpg.android.habitica.R;
|
||||
import com.habitrpg.android.habitica.components.AppComponent;
|
||||
import com.habitrpg.android.habitica.ui.activities.MainActivity;
|
||||
import com.habitrpg.android.habitica.ui.adapter.inventory.ShopRecyclerAdapter;
|
||||
import com.habitrpg.android.habitica.ui.adapter.inventory.StableRecyclerAdapter;
|
||||
import com.habitrpg.android.habitica.ui.fragments.BaseFragment;
|
||||
import com.habitrpg.android.habitica.ui.helpers.MarginDecoration;
|
||||
import com.habitrpg.android.habitica.ui.helpers.RecyclerViewEmptySupport;
|
||||
import com.habitrpg.android.habitica.ui.menu.DividerItemDecoration;
|
||||
import com.magicmicky.habitrpgwrapper.lib.models.HabitRPGUser;
|
||||
|
|
@ -15,7 +12,6 @@ import com.magicmicky.habitrpgwrapper.lib.models.Shop;
|
|||
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.widget.GridLayoutManager;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
|
|
@ -44,7 +40,7 @@ public class ShopFragment extends BaseFragment {
|
|||
public Shop shop;
|
||||
|
||||
@Inject
|
||||
APIHelper apiHeliper;
|
||||
APIHelper apiHelper;
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
|
|
@ -104,8 +100,8 @@ public class ShopFragment extends BaseFragment {
|
|||
shopUrl = "seasonal";
|
||||
break;
|
||||
}
|
||||
this.apiHeliper.apiService.fetchShopInventory(shopUrl)
|
||||
.compose(this.apiHeliper.configureApiCallObserver())
|
||||
this.apiHelper.apiService.fetchShopInventory(shopUrl)
|
||||
.compose(this.apiHelper.configureApiCallObserver())
|
||||
.subscribe(shop -> {
|
||||
this.shop = shop;
|
||||
this.adapter.setShop(shop);
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -5,6 +5,7 @@ import com.habitrpg.android.habitica.HabiticaApplication;
|
|||
import com.habitrpg.android.habitica.R;
|
||||
import com.habitrpg.android.habitica.components.AppComponent;
|
||||
import com.habitrpg.android.habitica.events.ToggledInnStateEvent;
|
||||
import com.habitrpg.android.habitica.events.commands.CopyChatMessageCommand;
|
||||
import com.habitrpg.android.habitica.events.commands.DeleteChatMessageCommand;
|
||||
import com.habitrpg.android.habitica.events.commands.FlagChatMessageCommand;
|
||||
import com.habitrpg.android.habitica.events.commands.SendNewGroupMessageCommand;
|
||||
|
|
@ -23,6 +24,9 @@ import com.raizlabs.android.dbflow.sql.language.Select;
|
|||
import org.greenrobot.eventbus.EventBus;
|
||||
import org.greenrobot.eventbus.Subscribe;
|
||||
|
||||
import android.content.ClipData;
|
||||
import android.content.ClipboardManager;
|
||||
import android.content.Context;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
|
|
@ -33,6 +37,7 @@ import android.support.v7.widget.RecyclerView;
|
|||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Toast;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
|
@ -159,6 +164,16 @@ public class ChatListFragment extends BaseFragment implements SwipeRefreshLayout
|
|||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onEvent(CopyChatMessageCommand cmd)
|
||||
{
|
||||
ClipboardManager clipMan = (ClipboardManager)getActivity().getSystemService(Context.CLIPBOARD_SERVICE);
|
||||
ClipData chatMessage = ClipData.newPlainText("Chat Message",cmd.chatMessage.text);
|
||||
clipMan.setPrimaryClip(chatMessage);
|
||||
MainActivity activity = (MainActivity) getActivity();
|
||||
UiUtils.showSnackbar(activity, activity.getFloatingMenuWrapper(), getString(R.string.chat_message_copied), UiUtils.SnackbarDisplayType.NORMAL);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onEvent(final FlagChatMessageCommand cmd) {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
||||
|
|
|
|||
|
|
@ -75,6 +75,9 @@ public interface ApiService {
|
|||
@POST("user/buy-mystery-set/{key}")
|
||||
Observable<Void> purchaseMysterySet(@Path("key") String itemKey);
|
||||
|
||||
@POST("user/buy-quest/{key}")
|
||||
Observable<Void> purchaseQuest(@Path("key") String key);
|
||||
|
||||
@POST("user/sell/{type}/{key}")
|
||||
Observable<HabitRPGUser> sellItem(@Path("type") String itemType, @Path("key") String itemKey);
|
||||
|
||||
|
|
@ -205,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 +241,17 @@ public interface ApiService {
|
|||
|
||||
@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")
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -60,6 +60,9 @@ public class ShopItem {
|
|||
}
|
||||
|
||||
public Boolean getLocked() {
|
||||
if (locked == null) {
|
||||
return false;
|
||||
}
|
||||
return locked;
|
||||
}
|
||||
|
||||
|
|
@ -90,4 +93,14 @@ public class ShopItem {
|
|||
public void setUnlockCondition(ShopItemUnlockCondition unlockCondition) {
|
||||
this.unlockCondition = unlockCondition;
|
||||
}
|
||||
|
||||
public boolean canBuy(HabitRPGUser user) {
|
||||
if (getCurrency().equals("gold")) {
|
||||
return getValue() <= user.getStats().getGp();
|
||||
} else if (getCurrency().equals("gems")) {
|
||||
return getValue() <= (user.getBalance()*4);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -603,7 +603,7 @@ public class Task extends BaseModel {
|
|||
Calendar newTime = new GregorianCalendar();
|
||||
newTime.setTime(oldTime);
|
||||
|
||||
if (this.getFrequency().equals(FREQUENCY_DAILY) && (newTime.before(today) || newTime.equals(today))) {
|
||||
if (this.getFrequency().equals(FREQUENCY_DAILY) ) {
|
||||
Calendar startDate = new GregorianCalendar();
|
||||
startDate.setTime(this.getStartDate());
|
||||
|
||||
|
|
@ -611,7 +611,9 @@ public class Task extends BaseModel {
|
|||
long diffInMillies = today.getTimeInMillis() - startDate.getTimeInMillis();
|
||||
long daySinceStart = timeUnit.convert(diffInMillies, TimeUnit.MILLISECONDS);
|
||||
long daysUntilNextReminder = this.getEveryX() - (daySinceStart % this.getEveryX());
|
||||
newTime.add(Calendar.DATE, (int) daysUntilNextReminder);
|
||||
|
||||
today.add(Calendar.DATE, (int) daysUntilNextReminder);
|
||||
newTime.setTime(today.getTime());
|
||||
} else {
|
||||
int nextActiveDayOfTheWeek = newTime.get(Calendar.DAY_OF_WEEK);
|
||||
while (!this.getRepeat().getForDay(nextActiveDayOfTheWeek) || newTime.before(today) || newTime.equals(today)) {
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import org.junit.After;
|
|||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.RobolectricGradleTestRunner;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.annotation.Config;
|
||||
|
||||
import android.os.Build;
|
||||
|
|
@ -23,8 +24,8 @@ import rx.observers.TestSubscriber;
|
|||
import static junit.framework.Assert.assertEquals;
|
||||
import static junit.framework.Assert.assertTrue;
|
||||
|
||||
@Config(constants = BuildConfig.class, sdk = Build.VERSION_CODES.LOLLIPOP)
|
||||
@RunWith(RobolectricGradleTestRunner.class)
|
||||
@Config(constants = BuildConfig.class, sdk = Build.VERSION_CODES.M)
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class SocialAPITests extends BaseAPITests {
|
||||
|
||||
List<String> messagesIDs;
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import android.os.Build;
|
|||
|
||||
import rx.observers.TestSubscriber;
|
||||
|
||||
@Config(constants = BuildConfig.class, sdk = Build.VERSION_CODES.LOLLIPOP)
|
||||
@Config(constants = BuildConfig.class, sdk = Build.VERSION_CODES.M)
|
||||
@RunWith(RobolectricGradleTestRunner.class)
|
||||
public class TagAPITests extends BaseAPITests {
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ import rx.observers.TestSubscriber;
|
|||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
@Config(constants = BuildConfig.class, sdk = Build.VERSION_CODES.LOLLIPOP)
|
||||
@Config(constants = BuildConfig.class, sdk = Build.VERSION_CODES.M)
|
||||
@RunWith(RobolectricGradleTestRunner.class)
|
||||
public class TaskAPITests extends BaseAPITests {
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ import rx.observers.TestSubscriber;
|
|||
import static junit.framework.Assert.assertEquals;
|
||||
import static junit.framework.Assert.assertNotSame;
|
||||
|
||||
@Config(constants = BuildConfig.class, sdk = Build.VERSION_CODES.LOLLIPOP)
|
||||
@Config(constants = BuildConfig.class, sdk = Build.VERSION_CODES.M)
|
||||
@RunWith(RobolectricGradleTestRunner.class)
|
||||
public class UserAPITests extends BaseAPITests {
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ public class RemindersManagerTest {
|
|||
|
||||
@Test
|
||||
public void itCreatesRemindersItemFromDateString() {
|
||||
RemindersManager remindersManager = new RemindersManager();
|
||||
RemindersManager remindersManager = new RemindersManager("habits");
|
||||
|
||||
// RemindersItem remindersItem = remindersManager.createReminderFromDateString("dd MMMM yyyy HH:mm:ss")
|
||||
|
||||
|
|
|
|||
|
|
@ -21,12 +21,14 @@ import org.junit.Test;
|
|||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.annotation.Config;
|
||||
import org.robolectric.shadows.ShadowApplication;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
|
@ -35,6 +37,7 @@ import static org.junit.Assert.assertNotNull;
|
|||
* Created by keithholliday on 7/16/16.
|
||||
*/
|
||||
|
||||
@Config(manifest = "AndroidManifestTesting.xml")
|
||||
@RunWith(value = RobolectricTestRunner.class)
|
||||
public class TaskAlarmManagerTest {
|
||||
private TaskAlarmManager taskAlarmManager;
|
||||
|
|
@ -59,6 +62,8 @@ public class TaskAlarmManagerTest {
|
|||
|
||||
List<RemindersItem> reminders = new ArrayList<RemindersItem>();
|
||||
RemindersItem remindersItem1 = new RemindersItem();
|
||||
UUID randomUUID = UUID.randomUUID();
|
||||
remindersItem1.setId(randomUUID.toString());
|
||||
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.set(Calendar.MINUTE, cal.get(Calendar.MINUTE) + 1);
|
||||
|
|
@ -71,14 +76,13 @@ public class TaskAlarmManagerTest {
|
|||
|
||||
taskAlarmManager.setAlarmsForTask(task);
|
||||
|
||||
Integer alarmId = reminders.get(0).getAlarmId();
|
||||
|
||||
int intentId = remindersItem1.getId().hashCode() & 0xfffffff;
|
||||
Intent intent = new Intent(context, TaskReceiver.class);
|
||||
intent.setAction(remindersItem1.getAlarmId().toString());
|
||||
PendingIntent sender = PendingIntent.getBroadcast(context, alarmId, intent, PendingIntent.FLAG_NO_CREATE);
|
||||
intent.setAction(remindersItem1.getId());
|
||||
PendingIntent sender = PendingIntent.getBroadcast(context, intentId, intent, PendingIntent.FLAG_NO_CREATE);
|
||||
boolean alarmUp = sender != null;
|
||||
|
||||
Assert.assertNotNull(alarmId);
|
||||
Assert.assertNotNull(intentId);
|
||||
Assert.assertEquals(true, alarmUp);
|
||||
}
|
||||
|
||||
|
|
@ -89,6 +93,8 @@ public class TaskAlarmManagerTest {
|
|||
|
||||
List<RemindersItem> reminders = new ArrayList<RemindersItem>();
|
||||
RemindersItem remindersItem1 = new RemindersItem();
|
||||
UUID randomUUID = UUID.randomUUID();
|
||||
remindersItem1.setId(randomUUID.toString());
|
||||
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.set(Calendar.MINUTE, cal.get(Calendar.MINUTE) + 1);
|
||||
|
|
@ -101,9 +107,9 @@ public class TaskAlarmManagerTest {
|
|||
|
||||
taskAlarmManager.setAlarmsForTask(task);
|
||||
|
||||
Integer alarmId = reminders.get(0).getAlarmId();
|
||||
int alarmId = remindersItem1.getId().hashCode() & 0xfffffff;
|
||||
Intent intent = new Intent(context, TaskReceiver.class);
|
||||
intent.setAction(remindersItem1.getAlarmId().toString());
|
||||
intent.setAction(remindersItem1.getId());
|
||||
PendingIntent sender = PendingIntent.getBroadcast(context, alarmId, intent, PendingIntent.FLAG_NO_CREATE);
|
||||
boolean alarmUp = sender != null;
|
||||
|
||||
|
|
@ -127,7 +133,7 @@ public class TaskAlarmManagerTest {
|
|||
}
|
||||
|
||||
taskAlarmManager.setAlarmsForTask(task);
|
||||
Integer newAlarmId = reminders.get(0).getAlarmId();
|
||||
int newAlarmId = reminders.get(0).getId().hashCode() & 0xfffffff;
|
||||
PendingIntent senderNew = PendingIntent.getBroadcast(context, newAlarmId, intent, PendingIntent.FLAG_NO_CREATE);
|
||||
boolean alarmUpNew = senderNew != null;
|
||||
|
||||
|
|
@ -192,6 +198,8 @@ public class TaskAlarmManagerTest {
|
|||
|
||||
List<RemindersItem> reminders = new ArrayList<RemindersItem>();
|
||||
RemindersItem remindersItem1 = new RemindersItem();
|
||||
UUID randomUUID = UUID.randomUUID();
|
||||
remindersItem1.setId(randomUUID.toString());
|
||||
|
||||
//We try to set a reminder on Tuesday, but the manager will correct this to Monday
|
||||
Calendar cal = Calendar.getInstance();
|
||||
|
|
@ -206,13 +214,13 @@ public class TaskAlarmManagerTest {
|
|||
|
||||
taskAlarmManager.setAlarmsForTask(task);
|
||||
|
||||
Integer alarmId = reminders.get(0).getAlarmId();
|
||||
int alarmId = reminders.get(0).getId().hashCode() & 0xfffffff;
|
||||
|
||||
Calendar newReminderTime = Calendar.getInstance();
|
||||
newReminderTime.setTime(reminders.get(0).getTime());
|
||||
|
||||
Intent intent = new Intent(context, TaskReceiver.class);
|
||||
intent.setAction(remindersItem1.getAlarmId().toString());
|
||||
intent.setAction(remindersItem1.getId());
|
||||
PendingIntent sender = PendingIntent.getBroadcast(context, alarmId, intent, PendingIntent.FLAG_NO_CREATE);
|
||||
boolean alarmUp = sender != null;
|
||||
|
||||
|
|
@ -240,6 +248,8 @@ public class TaskAlarmManagerTest {
|
|||
|
||||
List<RemindersItem> reminders = new ArrayList<RemindersItem>();
|
||||
RemindersItem remindersItem1 = new RemindersItem();
|
||||
UUID randomUUID = UUID.randomUUID();
|
||||
remindersItem1.setId(randomUUID.toString());
|
||||
|
||||
//We try to set a reminder for now, but by the manager will correct (because the seconds will be different)
|
||||
Calendar cal = Calendar.getInstance();
|
||||
|
|
@ -252,13 +262,13 @@ public class TaskAlarmManagerTest {
|
|||
|
||||
taskAlarmManager.setAlarmsForTask(task);
|
||||
|
||||
Integer alarmId = reminders.get(0).getAlarmId();
|
||||
int alarmId = reminders.get(0).getId().hashCode() & 0xfffffff;
|
||||
|
||||
Calendar newReminderTime = Calendar.getInstance();
|
||||
newReminderTime.setTime(reminders.get(0).getTime());
|
||||
|
||||
Intent intent = new Intent(context, TaskReceiver.class);
|
||||
intent.setAction(remindersItem1.getAlarmId().toString());
|
||||
intent.setAction(remindersItem1.getId());
|
||||
PendingIntent sender = PendingIntent.getBroadcast(context, alarmId, intent, PendingIntent.FLAG_NO_CREATE);
|
||||
boolean alarmUp = sender != null;
|
||||
|
||||
|
|
@ -278,13 +288,18 @@ public class TaskAlarmManagerTest {
|
|||
|
||||
List<RemindersItem> reminders = new ArrayList<RemindersItem>();
|
||||
RemindersItem remindersItem1 = new RemindersItem();
|
||||
UUID randomUUID = UUID.randomUUID();
|
||||
remindersItem1.setId(randomUUID.toString());
|
||||
|
||||
//We try to set a reminder one day after the start date, but the manager will correct since the
|
||||
// daily is every 2 days from above
|
||||
Calendar cal = Calendar.getInstance();
|
||||
int currentDayOfTheWeek = cal.get(Calendar.DAY_OF_WEEK);
|
||||
|
||||
task.setStartDate(cal.getTime());
|
||||
|
||||
cal.set(Calendar.DAY_OF_WEEK, currentDayOfTheWeek + 1);
|
||||
cal.set(Calendar.MINUTE, cal.get(Calendar.MINUTE) + 1);
|
||||
cal.set(Calendar.MINUTE, cal.get(Calendar.MINUTE));
|
||||
|
||||
remindersItem1.setTime(cal.getTime());
|
||||
reminders.add(remindersItem1);
|
||||
|
|
@ -294,13 +309,13 @@ public class TaskAlarmManagerTest {
|
|||
|
||||
taskAlarmManager.setAlarmsForTask(task);
|
||||
|
||||
Integer alarmId = reminders.get(0).getAlarmId();
|
||||
int alarmId = reminders.get(0).getId().hashCode() & 0xfffffff;
|
||||
|
||||
Calendar newReminderTime = Calendar.getInstance();
|
||||
newReminderTime.setTime(reminders.get(0).getTime());
|
||||
|
||||
Intent intent = new Intent(context, TaskReceiver.class);
|
||||
intent.setAction(remindersItem1.getAlarmId().toString());
|
||||
intent.setAction(remindersItem1.getId());
|
||||
PendingIntent sender = PendingIntent.getBroadcast(context, alarmId, intent, PendingIntent.FLAG_NO_CREATE);
|
||||
boolean alarmUp = sender != null;
|
||||
|
||||
|
|
@ -321,6 +336,8 @@ public class TaskAlarmManagerTest {
|
|||
|
||||
List<RemindersItem> reminders = new ArrayList<RemindersItem>();
|
||||
RemindersItem remindersItem1 = new RemindersItem();
|
||||
UUID randomUUID = UUID.randomUUID();
|
||||
remindersItem1.setId(randomUUID.toString());
|
||||
|
||||
//We try to set a reminder for now, but the manager will correct since the seconds will be off
|
||||
Calendar cal = Calendar.getInstance();
|
||||
|
|
@ -334,13 +351,13 @@ public class TaskAlarmManagerTest {
|
|||
|
||||
taskAlarmManager.setAlarmsForTask(task);
|
||||
|
||||
Integer alarmId = reminders.get(0).getAlarmId();
|
||||
int alarmId = reminders.get(0).getId().hashCode() & 0xfffffff;
|
||||
|
||||
Calendar newReminderTime = Calendar.getInstance();
|
||||
newReminderTime.setTime(reminders.get(0).getTime());
|
||||
|
||||
Intent intent = new Intent(context, TaskReceiver.class);
|
||||
intent.setAction(remindersItem1.getAlarmId().toString());
|
||||
intent.setAction(remindersItem1.getId());
|
||||
PendingIntent sender = PendingIntent.getBroadcast(context, alarmId, intent, PendingIntent.FLAG_NO_CREATE);
|
||||
boolean alarmUp = sender != null;
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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'
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
11
translations/store_strings-bg.xml
Normal file
11
translations/store_strings-bg.xml
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<resources>
|
||||
<string name="store_short_description">Превърнете живота си в игра за повече мотивация и по-добра организация!</string>
|
||||
<string name="store_description">НОВОТО приложение на Хабитика! Пренаписано изцяло за по-добро преживяване и повече функционалности.
|
||||
|
||||
Превърнете живота си в игра за повече мотивация и по-добра организация! С Хабитика е лесно да се забавлявате, докато изпълнявате целите си.
|
||||
|
||||
Въведете навиците си, ежедневните си цели и дългосрочните си задачи, а след това си създайте герой. Изпълнявайте задачите си, за да вдигате нивото на героя си и отключвате функционалности като екипировка, любимци, умения и дори мисии! Бийте се с чудовища заедно с приятели, за да държите един другиго отговорен, и използвайте златото си за награди като екипировка, или дори свои собствени такива, като например да гледате епизод от любимия си сериал. Гъвкава, забавна и с голяма общност, Хабитика е перфектният начин да се мотивирате и да постигнете всичко, което искате.
|
||||
|
||||
Версията в момента е „бета“, така че не се притеснявайте да ни изпращате отзивите си на mobile@habitica.com! А ако приложението Ви харесва, ще се радваме да оставите рецензията си.</string>
|
||||
</resources>
|
||||
Loading…
Reference in a new issue