mirror of
https://github.com/sudoxnym/habitica-android.git
synced 2026-07-13 17:51:57 +00:00
Implement party creation
This commit is contained in:
parent
81a9de01b9
commit
2edf68b474
21 changed files with 336 additions and 230 deletions
|
|
@ -122,7 +122,7 @@
|
||||||
</activity>
|
</activity>
|
||||||
<activity
|
<activity
|
||||||
android:name=".ui.activities.GroupFormActivity"
|
android:name=".ui.activities.GroupFormActivity"
|
||||||
android:theme="@style/AppThemeWithActionBarBlackText"
|
android:theme="@style/AppTheme.NoActionBar.Transparent"
|
||||||
android:parentActivityName=".ui.activities.MainActivity"
|
android:parentActivityName=".ui.activities.MainActivity"
|
||||||
android:screenOrientation="portrait"
|
android:screenOrientation="portrait"
|
||||||
tools:ignore="UnusedAttribute">
|
tools:ignore="UnusedAttribute">
|
||||||
|
|
|
||||||
16
Habitica/res/drawable/edittext.xml
Normal file
16
Habitica/res/drawable/edittext.xml
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item android:top="18dp">
|
||||||
|
<shape android:shape="rectangle">
|
||||||
|
<solid android:color="@color/gray_500" />
|
||||||
|
<corners android:radius="4dp" android:topLeftRadius="8dp" android:topRightRadius="8dp" />
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
|
||||||
|
<item android:bottom="2dp" android:top="18dp">
|
||||||
|
<shape android:shape="rectangle">
|
||||||
|
<solid android:color="@color/gray_700" />
|
||||||
|
<corners android:topLeftRadius="4dp" android:topRightRadius="4dp" android:bottomLeftRadius="2dp" android:bottomRightRadius="2dp" />
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
</layer-list>
|
||||||
|
|
@ -2,62 +2,130 @@
|
||||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:background="@color/gray_700">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content">
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingTop="30dp"
|
||||||
|
android:background="@color/white">
|
||||||
|
<LinearLayout
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
<ImageButton
|
||||||
|
android:id="@+id/cancel_button"
|
||||||
|
android:layout_width="50dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:src="@drawable/ic_close_purple_300_24dp"
|
||||||
|
style="@style/Base.Widget.AppCompat.Button.Borderless"
|
||||||
|
android:contentDescription="@string/cancel" />
|
||||||
|
<Space
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"/>
|
||||||
|
<Button
|
||||||
|
android:id="@+id/save_button"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/create"
|
||||||
|
style="@style/HabiticaButton"
|
||||||
|
android:textColor="@color/brand_400"
|
||||||
|
android:paddingEnd="@dimen/spacing_large"
|
||||||
|
android:paddingStart="@dimen/spacing_large"
|
||||||
|
android:minWidth="20dp"/>
|
||||||
|
</LinearLayout>
|
||||||
<com.google.android.material.textfield.TextInputLayout
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
app:hintTextAppearance="@style/TextAppearance.AppCompat">
|
app:hintTextAppearance="@style/TextAppearance.AppCompat"
|
||||||
<EditText
|
android:layout_marginTop="@dimen/spacing_small"
|
||||||
|
android:layout_marginLeft="@dimen/spacing_large"
|
||||||
|
android:layout_marginRight="@dimen/spacing_large"
|
||||||
|
android:background="@drawable/edittext"
|
||||||
|
android:textColorHint="@color/gray_50">
|
||||||
|
<MultiAutoCompleteTextView
|
||||||
android:id="@+id/group_name_edittext"
|
android:id="@+id/group_name_edittext"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="center_horizontal"
|
android:layout_gravity="center_horizontal"
|
||||||
android:hint="@string/name"
|
android:hint="@string/name"
|
||||||
android:textColor="@android:color/black"
|
android:textColor="@android:color/black"
|
||||||
android:inputType="textCapSentences" />
|
android:inputType="textCapSentences"
|
||||||
|
android:background="@color/transparent"
|
||||||
|
android:paddingStart="@dimen/spacing_large"
|
||||||
|
android:paddingEnd="@dimen/spacing_large"
|
||||||
|
android:paddingBottom="@dimen/spacing_large"
|
||||||
|
android:paddingTop="20dp"
|
||||||
|
android:textColorHint="@color/gray_50"
|
||||||
|
/>
|
||||||
</com.google.android.material.textfield.TextInputLayout>
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="72dp"
|
|
||||||
android:orientation="horizontal" >
|
|
||||||
|
|
||||||
<ImageButton
|
|
||||||
android:id="@+id/emoji.toggle.btn"
|
|
||||||
android:layout_width="48dp"
|
|
||||||
android:layout_height="48dp"
|
|
||||||
android:src="@drawable/ic_emoticon_grey600_24dp"
|
|
||||||
android:background="@drawable/md_transparent"
|
|
||||||
android:contentDescription="Toogle Emoji"
|
|
||||||
android:focusable="true"
|
|
||||||
android:focusableInTouchMode="true" />
|
|
||||||
|
|
||||||
<com.google.android.material.textfield.TextInputLayout
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
app:hintTextAppearance="@style/TextAppearance.AppCompat">
|
app:hintTextAppearance="@style/TextAppearance.AppCompat"
|
||||||
|
android:layout_marginTop="@dimen/spacing_large"
|
||||||
|
android:layout_marginLeft="@dimen/spacing_large"
|
||||||
|
android:layout_marginRight="@dimen/spacing_large"
|
||||||
|
android:background="@drawable/edittext"
|
||||||
|
android:textColorHint="@color/gray_50">
|
||||||
|
|
||||||
<net.pherth.android.emoji_library.EmojiEditText
|
<MultiAutoCompleteTextView
|
||||||
android:id="@+id/group_description_edittext"
|
android:id="@+id/group_description_edittext"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="center_horizontal"
|
android:layout_gravity="center_horizontal"
|
||||||
android:hint="@string/description"
|
android:hint="@string/description"
|
||||||
android:textColor="@android:color/black"
|
android:textColor="@android:color/black"
|
||||||
android:inputType="textCapSentences|textMultiLine" />
|
android:inputType="textCapSentences|textMultiLine"
|
||||||
|
android:background="@color/transparent"
|
||||||
|
android:paddingStart="@dimen/spacing_large"
|
||||||
|
android:paddingEnd="@dimen/spacing_large"
|
||||||
|
android:paddingBottom="@dimen/spacing_large"
|
||||||
|
android:paddingTop="20dp"
|
||||||
|
android:textColorHint="@color/gray_50"
|
||||||
|
android:minLines="3"
|
||||||
|
android:gravity="top" />
|
||||||
</com.google.android.material.textfield.TextInputLayout>
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="@dimen/spacing_large"
|
||||||
|
android:layout_marginLeft="@dimen/spacing_large"
|
||||||
|
android:layout_marginRight="@dimen/spacing_large">
|
||||||
|
<TextView
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/only_leader_create_challenge"/>
|
||||||
|
<Switch
|
||||||
|
android:id="@+id/leader_create_challenge_switch"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
/>
|
||||||
|
</LinearLayout>
|
||||||
|
<View
|
||||||
|
android:id="@+id/privacy_separator"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="1dp"
|
||||||
|
android:background="#1e000000"
|
||||||
|
android:layout_marginTop="@dimen/spacing_medium"
|
||||||
|
android:layout_marginBottom="@dimen/spacing_medium"
|
||||||
|
tools:visibility="gone" />
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:id="@+id/privacyWrapper">
|
android:id="@+id/privacyWrapper"
|
||||||
|
android:layout_marginLeft="@dimen/spacing_large"
|
||||||
|
android:layout_marginRight="@dimen/spacing_large"
|
||||||
|
tools:visibility="gone">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
|
|
@ -70,5 +138,10 @@
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:id="@+id/privacySpinner" />
|
android:id="@+id/privacySpinner" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
<View
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="1dp"
|
||||||
|
android:background="#1e000000"
|
||||||
|
android:layout_marginTop="@dimen/spacing_medium" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
|
|
@ -111,7 +111,7 @@
|
||||||
style="@style/HabiticaButton.Gray.600"
|
style="@style/HabiticaButton.Gray.600"
|
||||||
android:background="@drawable/layout_rounded_bg_gray_700"
|
android:background="@drawable/layout_rounded_bg_gray_700"
|
||||||
android:textSize="16sp"
|
android:textSize="16sp"
|
||||||
android:text="@string/create_party_website"
|
android:text="@string/create_party"
|
||||||
android:layout_marginTop="@dimen/spacing_large"/>
|
android:layout_marginTop="@dimen/spacing_large"/>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
<View
|
<View
|
||||||
|
|
|
||||||
|
|
@ -10,4 +10,9 @@
|
||||||
android:orderInCategory="1"
|
android:orderInCategory="1"
|
||||||
app:showAsAction="never"
|
app:showAsAction="never"
|
||||||
android:title="@string/action_edit" />
|
android:title="@string/action_edit" />
|
||||||
|
<item
|
||||||
|
android:id="@+id/menu.guild.leave"
|
||||||
|
android:orderInCategory="1"
|
||||||
|
app:showAsAction="never"
|
||||||
|
android:title="@string/leave" />
|
||||||
</menu>
|
</menu>
|
||||||
|
|
@ -256,4 +256,8 @@
|
||||||
android:name="userID"
|
android:name="userID"
|
||||||
app:argType="string" />
|
app:argType="string" />
|
||||||
</activity>
|
</activity>
|
||||||
|
<activity
|
||||||
|
android:id="@+id/groupFormActivity"
|
||||||
|
android:name="com.habitrpg.android.habitica.ui.activities.GroupFormActivity"
|
||||||
|
android:label="GroupFormActivity" />
|
||||||
</navigation>
|
</navigation>
|
||||||
|
|
@ -860,5 +860,8 @@
|
||||||
<string name="discover">Discover</string>
|
<string name="discover">Discover</string>
|
||||||
<string name="damage_paused">Damage paused</string>
|
<string name="damage_paused">Damage paused</string>
|
||||||
<string name="preference_push_important_announcements">Important Announcements</string>
|
<string name="preference_push_important_announcements">Important Announcements</string>
|
||||||
|
<string name="create">Create</string>
|
||||||
|
<string name="only_leader_create_challenge">Only leader can create Challenges</string>
|
||||||
|
<string name="create_party">Create Party</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
||||||
|
|
@ -201,6 +201,9 @@ public interface ApiService {
|
||||||
@GET("groups/{gid}")
|
@GET("groups/{gid}")
|
||||||
Flowable<HabitResponse<Group>> getGroup(@Path("gid") String groupId);
|
Flowable<HabitResponse<Group>> getGroup(@Path("gid") String groupId);
|
||||||
|
|
||||||
|
@POST("groups")
|
||||||
|
Flowable<HabitResponse<Group>> createGroup(@Body Group item);
|
||||||
|
|
||||||
@PUT("groups/{id}")
|
@PUT("groups/{id}")
|
||||||
Flowable<HabitResponse<Void>> updateGroup(@Path("id") String id, @Body Group item);
|
Flowable<HabitResponse<Void>> updateGroup(@Path("id") String id, @Body Group item);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -129,6 +129,7 @@ interface ApiClient {
|
||||||
|
|
||||||
fun getGroup(groupId: String): Flowable<Group>
|
fun getGroup(groupId: String): Flowable<Group>
|
||||||
|
|
||||||
|
fun createGroup(group: Group): Flowable<Group>
|
||||||
fun updateGroup(id: String, item: Group): Flowable<Void>
|
fun updateGroup(id: String, item: Group): Flowable<Void>
|
||||||
|
|
||||||
fun listGroupChat(groupId: String): Flowable<List<ChatMessage>>
|
fun listGroupChat(groupId: String): Flowable<List<ChatMessage>>
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,8 @@ interface SocialRepository : BaseRepository {
|
||||||
|
|
||||||
fun joinGroup(id: String?): Flowable<Group>
|
fun joinGroup(id: String?): Flowable<Group>
|
||||||
|
|
||||||
fun updateGroup(group: Group?, name: String?, description: String?, leader: String?, privacy: String?): Flowable<Void>
|
fun createGroup(name: String?, description: String?, leader: String?, type: String?, privacy: String?, leaderCreateChallenge: Boolean?): Flowable<Group>
|
||||||
|
fun updateGroup(group: Group?, name: String?, description: String?, leader: String?, leaderCreateChallenge: Boolean?): Flowable<Void>
|
||||||
|
|
||||||
fun retrieveGroups(type: String): Flowable<List<Group>>
|
fun retrieveGroups(type: String): Flowable<List<Group>>
|
||||||
fun getGroups(type: String): Flowable<RealmResults<Group>>
|
fun getGroups(type: String): Flowable<RealmResults<Group>>
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,7 @@ class ApiClientImpl//private OnHabitsAPIResult mResultListener;
|
||||||
//private HostConfig mConfig;
|
//private HostConfig mConfig;
|
||||||
(private val gsonConverter: GsonConverterFactory, override val hostConfig: HostConfig, private val crashlyticsProxy: CrashlyticsProxy, private val popupNotificationsManager: PopupNotificationsManager, private val context: Context) : Consumer<Throwable>, ApiClient {
|
(private val gsonConverter: GsonConverterFactory, override val hostConfig: HostConfig, private val crashlyticsProxy: CrashlyticsProxy, private val popupNotificationsManager: PopupNotificationsManager, private val context: Context) : Consumer<Throwable>, ApiClient {
|
||||||
|
|
||||||
|
|
||||||
private lateinit var retrofitAdapter: Retrofit
|
private lateinit var retrofitAdapter: Retrofit
|
||||||
|
|
||||||
// I think we don't need the ApiClientImpl anymore we could just use ApiService
|
// I think we don't need the ApiClientImpl anymore we could just use ApiService
|
||||||
|
|
@ -476,6 +477,10 @@ class ApiClientImpl//private OnHabitsAPIResult mResultListener;
|
||||||
return apiService.getGroup(groupId).compose(configureApiCallObserver())
|
return apiService.getGroup(groupId).compose(configureApiCallObserver())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun createGroup(group: Group): Flowable<Group> {
|
||||||
|
return apiService.createGroup(group).compose(configureApiCallObserver())
|
||||||
|
}
|
||||||
|
|
||||||
override fun updateGroup(id: String, item: Group): Flowable<Void> {
|
override fun updateGroup(id: String, item: Group): Flowable<Void> {
|
||||||
return apiService.updateGroup(id, item).compose(configureApiCallObserver())
|
return apiService.updateGroup(id, item).compose(configureApiCallObserver())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ import io.realm.RealmResults
|
||||||
|
|
||||||
class SocialRepositoryImpl(localRepository: SocialLocalRepository, apiClient: ApiClient, userID: String) : BaseRepositoryImpl<SocialLocalRepository>(localRepository, apiClient, userID), SocialRepository {
|
class SocialRepositoryImpl(localRepository: SocialLocalRepository, apiClient: ApiClient, userID: String) : BaseRepositoryImpl<SocialLocalRepository>(localRepository, apiClient, userID), SocialRepository {
|
||||||
|
|
||||||
|
|
||||||
override fun getGroupMembership(id: String): Flowable<GroupMembership> {
|
override fun getGroupMembership(id: String): Flowable<GroupMembership> {
|
||||||
return localRepository.getGroupMembership(userID, id)
|
return localRepository.getGroupMembership(userID, id)
|
||||||
}
|
}
|
||||||
|
|
@ -131,7 +132,19 @@ class SocialRepositoryImpl(localRepository: SocialLocalRepository, apiClient: Ap
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun updateGroup(group: Group?, name: String?, description: String?, leader: String?, privacy: String?): Flowable<Void> {
|
override fun createGroup(name: String?, description: String?, leader: String?, type: String?, privacy: String?, leaderCreateChallenge: Boolean?): Flowable<Group> {
|
||||||
|
val group = Group()
|
||||||
|
group.name = name
|
||||||
|
group.description = description
|
||||||
|
group.type = type
|
||||||
|
group.leaderID = leader
|
||||||
|
group.privacy = privacy
|
||||||
|
return apiClient.createGroup(group).doOnNext {
|
||||||
|
localRepository.save(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun updateGroup(group: Group?, name: String?, description: String?, leader: String?, leaderCreateChallenge: Boolean?): Flowable<Void> {
|
||||||
if (group == null) {
|
if (group == null) {
|
||||||
return Flowable.empty()
|
return Flowable.empty()
|
||||||
}
|
}
|
||||||
|
|
@ -139,7 +152,7 @@ class SocialRepositoryImpl(localRepository: SocialLocalRepository, apiClient: Ap
|
||||||
copiedGroup.name = name
|
copiedGroup.name = name
|
||||||
copiedGroup.description = description
|
copiedGroup.description = description
|
||||||
copiedGroup.leaderID = leader
|
copiedGroup.leaderID = leader
|
||||||
copiedGroup.privacy = privacy
|
copiedGroup.leaderOnlyChallenges = leaderCreateChallenge ?: false
|
||||||
localRepository.save(copiedGroup)
|
localRepository.save(copiedGroup)
|
||||||
return apiClient.updateGroup(copiedGroup.id, copiedGroup)
|
return apiClient.updateGroup(copiedGroup.id, copiedGroup)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,34 +13,22 @@ open class Group : RealmObject() {
|
||||||
@SerializedName("_id")
|
@SerializedName("_id")
|
||||||
@PrimaryKey
|
@PrimaryKey
|
||||||
var id: String = ""
|
var id: String = ""
|
||||||
|
|
||||||
var balance: Double = 0.toDouble()
|
var balance: Double = 0.toDouble()
|
||||||
|
|
||||||
var description: String? = null
|
var description: String? = null
|
||||||
|
|
||||||
var summary: String? = null
|
var summary: String? = null
|
||||||
|
|
||||||
var leaderID: String? = null
|
var leaderID: String? = null
|
||||||
|
|
||||||
var leaderName: String? = null
|
var leaderName: String? = null
|
||||||
|
|
||||||
var name: String? = null
|
var name: String? = null
|
||||||
|
|
||||||
var memberCount: Int = 0
|
var memberCount: Int = 0
|
||||||
|
|
||||||
var type: String? = null
|
var type: String? = null
|
||||||
|
|
||||||
var logo: String? = null
|
var logo: String? = null
|
||||||
|
|
||||||
var quest: Quest? = null
|
var quest: Quest? = null
|
||||||
|
|
||||||
var privacy: String? = null
|
var privacy: String? = null
|
||||||
|
|
||||||
var members: RealmList<User>? = null
|
var members: RealmList<User>? = null
|
||||||
|
|
||||||
var challengeCount: Int = 0
|
var challengeCount: Int = 0
|
||||||
|
|
||||||
var leaderMessage: String? = null
|
var leaderMessage: String? = null
|
||||||
|
var leaderOnlyChallenges: Boolean = false
|
||||||
|
var leaderOnlyGetGems: Boolean = false
|
||||||
|
|
||||||
override fun equals(other: Any?): Boolean {
|
override fun equals(other: Any?): Boolean {
|
||||||
if (this === other) {
|
if (this === other) {
|
||||||
|
|
|
||||||
|
|
@ -1,45 +1,35 @@
|
||||||
package com.habitrpg.android.habitica.ui.activities
|
package com.habitrpg.android.habitica.ui.activities
|
||||||
|
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import android.content.Context
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import androidx.core.content.ContextCompat
|
|
||||||
import android.view.KeyEvent
|
|
||||||
import android.view.Menu
|
|
||||||
import android.view.MenuItem
|
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.inputmethod.InputMethodManager
|
import android.widget.*
|
||||||
import android.widget.EditText
|
|
||||||
import android.widget.ImageButton
|
|
||||||
import android.widget.LinearLayout
|
|
||||||
import android.widget.Spinner
|
|
||||||
import com.habitrpg.android.habitica.R
|
import com.habitrpg.android.habitica.R
|
||||||
import com.habitrpg.android.habitica.components.AppComponent
|
import com.habitrpg.android.habitica.components.AppComponent
|
||||||
import com.habitrpg.android.habitica.ui.helpers.KeyboardUtil
|
import com.habitrpg.android.habitica.extensions.notNull
|
||||||
import com.habitrpg.android.habitica.ui.helpers.MarkdownParser
|
import com.habitrpg.android.habitica.ui.helpers.*
|
||||||
import com.habitrpg.android.habitica.ui.helpers.bindView
|
|
||||||
import net.pherth.android.emoji_library.EmojiEditText
|
|
||||||
import net.pherth.android.emoji_library.EmojiPopup
|
|
||||||
|
|
||||||
class GroupFormActivity : BaseActivity() {
|
class GroupFormActivity : BaseActivity() {
|
||||||
|
|
||||||
private var groupID: String? = null
|
private var groupID: String? = null
|
||||||
|
private var groupType: String? = null
|
||||||
private var groupName: String? = null
|
private var groupName: String? = null
|
||||||
private var groupDescription: String? = null
|
private var groupDescription: String? = null
|
||||||
private var groupPrivacy: String? = null
|
private var groupPrivacy: String? = null
|
||||||
private var groupLeader: String? = null
|
private var groupLeader: String? = null
|
||||||
|
private var leaderCreateChallenge = false
|
||||||
|
|
||||||
private val groupNameEditText: EditText by bindView(R.id.group_name_edittext)
|
private val cancelButton: ImageButton by bindView(R.id.cancel_button)
|
||||||
private val groupDescriptionEditText: EmojiEditText by bindView(R.id.group_description_edittext)
|
private val saveButton: Button by bindView(R.id.save_button)
|
||||||
internal val emojiButton: ImageButton by bindView(R.id.emoji_toggle_btn)
|
private val groupNameEditText: MultiAutoCompleteTextView by bindView(R.id.group_name_edittext)
|
||||||
internal val privacyWrapper: LinearLayout by bindView(R.id.privacyWrapper)
|
private val groupDescriptionEditText: MultiAutoCompleteTextView by bindView(R.id.group_description_edittext)
|
||||||
|
private val leaderCreateChallengeSwitch: Switch by bindView(R.id.leader_create_challenge_switch)
|
||||||
|
private val privacyWrapper: LinearLayout by bindView(R.id.privacyWrapper)
|
||||||
internal val privacySpinner: Spinner by bindView(R.id.privacySpinner)
|
internal val privacySpinner: Spinner by bindView(R.id.privacySpinner)
|
||||||
|
private val privacySeparator: View by bindView(R.id.privacy_separator)
|
||||||
|
|
||||||
private val popup: EmojiPopup by lazy {
|
private var autocompleteAdapter: AutocompleteAdapter? = null
|
||||||
EmojiPopup(emojiButton.rootView, this, ContextCompat.getColor(this, R.color.brand))
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
override fun getLayoutResId(): Int {
|
override fun getLayoutResId(): Int {
|
||||||
return R.layout.activity_group_form
|
return R.layout.activity_group_form
|
||||||
|
|
@ -48,61 +38,34 @@ class GroupFormActivity : BaseActivity() {
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
val intent = intent
|
intent.extras.notNull {bundle ->
|
||||||
val bundle = intent.extras
|
groupID = bundle.getString("groupID")
|
||||||
this.groupID = bundle!!.getString("groupID")
|
groupType = bundle.getString("groupType")
|
||||||
this.groupName = bundle.getString("name")
|
groupName = bundle.getString("name")
|
||||||
this.groupDescription = bundle.getString("description")
|
groupDescription = bundle.getString("description")
|
||||||
this.groupPrivacy = bundle.getString("privacy")
|
groupPrivacy = bundle.getString("privacy")
|
||||||
this.groupLeader = bundle.getString("leader")
|
groupLeader = bundle.getString("leader")
|
||||||
|
leaderCreateChallenge = bundle.getBoolean("leaderCreateChallenge", false)
|
||||||
// Emoji keyboard stuff
|
|
||||||
|
|
||||||
popup
|
|
||||||
|
|
||||||
popup.setSizeForSoftKeyboard()
|
|
||||||
popup.setOnDismissListener { changeEmojiKeyboardIcon(false) }
|
|
||||||
popup.setOnSoftKeyboardOpenCloseListener(object : EmojiPopup.OnSoftKeyboardOpenCloseListener {
|
|
||||||
|
|
||||||
override fun onKeyboardOpen(keyBoardHeight: Int) {
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onKeyboardClose() {
|
|
||||||
if (popup.isShowing) {
|
|
||||||
popup.dismiss()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
popup.setOnEmojiconClickedListener { emojicon ->
|
|
||||||
if (currentFocus == null || !isEmojiEditText(currentFocus) || emojicon == null) {
|
|
||||||
return@setOnEmojiconClickedListener
|
|
||||||
}
|
|
||||||
val emojiEditText = currentFocus as? EmojiEditText
|
|
||||||
val start = emojiEditText?.selectionStart ?: 0
|
|
||||||
val end = emojiEditText?.selectionEnd ?: 0
|
|
||||||
if (start < 0) {
|
|
||||||
emojiEditText?.append(emojicon.emoji)
|
|
||||||
} else {
|
|
||||||
emojiEditText?.text?.replace(Math.min(start, end),
|
|
||||||
Math.max(start, end), emojicon.emoji, 0,
|
|
||||||
emojicon.emoji.length)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
popup.setOnEmojiconBackspaceClickedListener { _ ->
|
if (groupType == "party") {
|
||||||
if (isEmojiEditText(currentFocus)) {
|
privacyWrapper.visibility = View.GONE
|
||||||
val event = KeyEvent(
|
privacySeparator.visibility = View.GONE
|
||||||
0, 0, 0, KeyEvent.KEYCODE_DEL, 0, 0, 0, 0, KeyEvent.KEYCODE_ENDCALL)
|
|
||||||
currentFocus?.dispatchKeyEvent(event)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
emojiButton.setOnClickListener(EmojiClickListener(groupDescriptionEditText))
|
if (groupID != null) {
|
||||||
|
fillForm()
|
||||||
if (this.groupID != null) {
|
|
||||||
this.fillForm()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cancelButton.setOnClickListener {
|
||||||
|
finish()
|
||||||
|
KeyboardUtil.dismissKeyboard(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
saveButton.setOnClickListener {
|
||||||
|
finishActivitySuccessfuly()
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -111,43 +74,11 @@ class GroupFormActivity : BaseActivity() {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun fillForm() {
|
private fun fillForm() {
|
||||||
this.groupNameEditText.setText(this.groupName)
|
groupNameEditText.setText(groupName)
|
||||||
this.groupDescriptionEditText.setText(this.groupDescription)
|
groupDescriptionEditText.setText(groupDescription)
|
||||||
this.privacyWrapper.visibility = View.GONE
|
leaderCreateChallengeSwitch.isChecked = leaderCreateChallenge
|
||||||
}
|
privacyWrapper.visibility = View.GONE
|
||||||
|
saveButton.text = getString(R.string.save)
|
||||||
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
|
||||||
// Inflate the menu; this adds items to the action bar if it is present.
|
|
||||||
menuInflater.inflate(R.menu.menu_save, menu)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
|
||||||
// Handle action bar item clicks here. The action bar will
|
|
||||||
// automatically handle clicks on the Home/Up button, so long
|
|
||||||
// as you specify a parent activity in AndroidManifest.xml.
|
|
||||||
val id = item.itemId
|
|
||||||
|
|
||||||
|
|
||||||
if (id == R.id.action_save_changes) {
|
|
||||||
finishActivitySuccessfuly()
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
return super.onOptionsItemSelected(item)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun isEmojiEditText(view: View?): Boolean {
|
|
||||||
return view is EmojiEditText
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun changeEmojiKeyboardIcon(keyboardOpened: Boolean) {
|
|
||||||
|
|
||||||
if (keyboardOpened) {
|
|
||||||
emojiButton.setImageDrawable(ContextCompat.getDrawable(this, R.drawable.ic_keyboard_grey600_24dp))
|
|
||||||
} else {
|
|
||||||
emojiButton.setImageDrawable(ContextCompat.getDrawable(this, R.drawable.ic_emoticon_grey600_24dp))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onSupportNavigateUp(): Boolean {
|
override fun onSupportNavigateUp(): Boolean {
|
||||||
|
|
@ -165,7 +96,9 @@ class GroupFormActivity : BaseActivity() {
|
||||||
val resultIntent = Intent()
|
val resultIntent = Intent()
|
||||||
val bundle = Bundle()
|
val bundle = Bundle()
|
||||||
bundle.putString("name", this.groupNameEditText.text.toString())
|
bundle.putString("name", this.groupNameEditText.text.toString())
|
||||||
|
bundle.putString("groupType", groupType)
|
||||||
bundle.putString("description", MarkdownParser.parseCompiled(this.groupDescriptionEditText.text))
|
bundle.putString("description", MarkdownParser.parseCompiled(this.groupDescriptionEditText.text))
|
||||||
|
bundle.putBoolean("leaderCreateChallenge", leaderCreateChallengeSwitch.isActivated)
|
||||||
bundle.putString("leader", this.groupLeader)
|
bundle.putString("leader", this.groupLeader)
|
||||||
resultIntent.putExtras(bundle)
|
resultIntent.putExtras(bundle)
|
||||||
setResult(Activity.RESULT_OK, resultIntent)
|
setResult(Activity.RESULT_OK, resultIntent)
|
||||||
|
|
@ -173,28 +106,6 @@ class GroupFormActivity : BaseActivity() {
|
||||||
KeyboardUtil.dismissKeyboard(this)
|
KeyboardUtil.dismissKeyboard(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
private inner class EmojiClickListener(internal var view: EmojiEditText) : View.OnClickListener {
|
|
||||||
|
|
||||||
override fun onClick(v: View) {
|
|
||||||
if (!popup.isShowing) {
|
|
||||||
if (popup.isKeyBoardOpen == true) {
|
|
||||||
popup.showAtBottom()
|
|
||||||
changeEmojiKeyboardIcon(true)
|
|
||||||
} else {
|
|
||||||
view.isFocusableInTouchMode = true
|
|
||||||
view.requestFocus()
|
|
||||||
popup.showAtBottomPending()
|
|
||||||
val inputMethodManager = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
|
|
||||||
inputMethodManager.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT)
|
|
||||||
changeEmojiKeyboardIcon(true)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
popup.dismiss()
|
|
||||||
changeEmojiKeyboardIcon(false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
const val GROUP_FORM_ACTIVITY = 11
|
const val GROUP_FORM_ACTIVITY = 11
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
package com.habitrpg.android.habitica.ui.fragments.social
|
package com.habitrpg.android.habitica.ui.fragments.social
|
||||||
|
|
||||||
|
import android.app.Activity
|
||||||
import android.content.ClipData
|
import android.content.ClipData
|
||||||
import android.content.ClipboardManager
|
import android.content.ClipboardManager
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
|
@ -7,24 +8,24 @@ import android.content.Intent
|
||||||
import android.graphics.Bitmap
|
import android.graphics.Bitmap
|
||||||
import android.graphics.Shader
|
import android.graphics.Shader
|
||||||
import android.graphics.drawable.BitmapDrawable
|
import android.graphics.drawable.BitmapDrawable
|
||||||
import android.net.Uri
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.text.method.LinkMovementMethod
|
import android.text.method.LinkMovementMethod
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.core.net.toUri
|
|
||||||
import com.habitrpg.android.habitica.R
|
import com.habitrpg.android.habitica.R
|
||||||
import com.habitrpg.android.habitica.components.AppComponent
|
import com.habitrpg.android.habitica.components.AppComponent
|
||||||
import com.habitrpg.android.habitica.data.SocialRepository
|
import com.habitrpg.android.habitica.data.SocialRepository
|
||||||
import com.habitrpg.android.habitica.data.UserRepository
|
import com.habitrpg.android.habitica.data.UserRepository
|
||||||
import com.habitrpg.android.habitica.extensions.backgroundCompat
|
import com.habitrpg.android.habitica.extensions.backgroundCompat
|
||||||
import com.habitrpg.android.habitica.extensions.notNull
|
import com.habitrpg.android.habitica.extensions.notNull
|
||||||
|
import com.habitrpg.android.habitica.helpers.MainNavigationController
|
||||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||||
import com.habitrpg.android.habitica.models.invitations.PartyInvite
|
import com.habitrpg.android.habitica.models.invitations.PartyInvite
|
||||||
import com.habitrpg.android.habitica.models.members.Member
|
import com.habitrpg.android.habitica.models.members.Member
|
||||||
import com.habitrpg.android.habitica.models.social.Group
|
import com.habitrpg.android.habitica.models.social.Group
|
||||||
import com.habitrpg.android.habitica.models.user.User
|
import com.habitrpg.android.habitica.models.user.User
|
||||||
|
import com.habitrpg.android.habitica.ui.activities.GroupFormActivity
|
||||||
import com.habitrpg.android.habitica.ui.activities.MainActivity
|
import com.habitrpg.android.habitica.ui.activities.MainActivity
|
||||||
import com.habitrpg.android.habitica.ui.fragments.BaseFragment
|
import com.habitrpg.android.habitica.ui.fragments.BaseFragment
|
||||||
import com.habitrpg.android.habitica.ui.helpers.DataBindingUtils
|
import com.habitrpg.android.habitica.ui.helpers.DataBindingUtils
|
||||||
|
|
@ -71,7 +72,7 @@ class GroupInformationFragment : BaseFragment() {
|
||||||
|
|
||||||
updateGroup(group)
|
updateGroup(group)
|
||||||
|
|
||||||
buttonPartyInviteAccept.setOnClickListener { _ ->
|
buttonPartyInviteAccept.setOnClickListener {
|
||||||
val userId = user?.invitations?.party?.id
|
val userId = user?.invitations?.party?.id
|
||||||
if (userId != null) {
|
if (userId != null) {
|
||||||
socialRepository.joinGroup(userId)
|
socialRepository.joinGroup(userId)
|
||||||
|
|
@ -83,7 +84,7 @@ class GroupInformationFragment : BaseFragment() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
buttonPartyInviteReject.setOnClickListener { _ ->
|
buttonPartyInviteReject.setOnClickListener {
|
||||||
val userId = user?.invitations?.party?.id
|
val userId = user?.invitations?.party?.id
|
||||||
if (userId != null) {
|
if (userId != null) {
|
||||||
socialRepository.rejectGroupInvite(userId)
|
socialRepository.rejectGroupInvite(userId)
|
||||||
|
|
@ -91,7 +92,7 @@ class GroupInformationFragment : BaseFragment() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
username_textview.setOnClickListener { _ ->
|
username_textview.setOnClickListener {
|
||||||
val clipboard = context?.getSystemService(Context.CLIPBOARD_SERVICE) as? ClipboardManager
|
val clipboard = context?.getSystemService(Context.CLIPBOARD_SERVICE) as? ClipboardManager
|
||||||
val clip = ClipData.newPlainText(context?.getString(R.string.username), user?.username)
|
val clip = ClipData.newPlainText(context?.getString(R.string.username), user?.username)
|
||||||
clipboard?.primaryClip = clip
|
clipboard?.primaryClip = clip
|
||||||
|
|
@ -102,16 +103,21 @@ class GroupInformationFragment : BaseFragment() {
|
||||||
}
|
}
|
||||||
|
|
||||||
craetePartyButton.setOnClickListener {
|
craetePartyButton.setOnClickListener {
|
||||||
val browserIntent = Intent(Intent.ACTION_VIEW, "https://habitica.com/party".toUri())
|
val bundle = Bundle()
|
||||||
startActivity(browserIntent)
|
bundle.putString("groupType", "party")
|
||||||
|
bundle.putString("leader", user?.id)
|
||||||
|
val intent = Intent(activity, GroupFormActivity::class.java)
|
||||||
|
intent.putExtras(bundle)
|
||||||
|
intent.flags = Intent.FLAG_ACTIVITY_REORDER_TO_FRONT
|
||||||
|
startActivityForResult(intent, GroupFormActivity.GROUP_FORM_ACTIVITY)
|
||||||
}
|
}
|
||||||
|
|
||||||
context.notNull { context ->
|
context.notNull { context ->
|
||||||
DataBindingUtils.loadImage("timeTravelersShop_background_fall") {
|
DataBindingUtils.loadImage("timeTravelersShop_background_fall") {bitmap ->
|
||||||
val aspectRatio = it.width / it.height.toFloat()
|
val aspectRatio = bitmap.width / bitmap.height.toFloat()
|
||||||
val height = context.resources.getDimension(R.dimen.shop_height).toInt()
|
val height = context.resources.getDimension(R.dimen.shop_height).toInt()
|
||||||
val width = Math.round(height * aspectRatio)
|
val width = Math.round(height * aspectRatio)
|
||||||
val drawable = BitmapDrawable(context.resources, Bitmap.createScaledBitmap(it, width, height, false))
|
val drawable = BitmapDrawable(context.resources, Bitmap.createScaledBitmap(bitmap, width, height, false))
|
||||||
drawable.tileModeX = Shader.TileMode.REPEAT
|
drawable.tileModeX = Shader.TileMode.REPEAT
|
||||||
Observable.just(drawable)
|
Observable.just(drawable)
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
|
@ -125,6 +131,37 @@ class GroupInformationFragment : BaseFragment() {
|
||||||
groupSummaryView.movementMethod = LinkMovementMethod.getInstance()
|
groupSummaryView.movementMethod = LinkMovementMethod.getInstance()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||||
|
super.onActivityResult(requestCode, resultCode, data)
|
||||||
|
when (requestCode) {
|
||||||
|
GroupFormActivity.GROUP_FORM_ACTIVITY -> {
|
||||||
|
if (resultCode == Activity.RESULT_OK) {
|
||||||
|
val bundle = data?.extras
|
||||||
|
if (bundle?.getString("groupType") == "party") {
|
||||||
|
socialRepository.createGroup(bundle.getString("name"),
|
||||||
|
bundle.getString("description"),
|
||||||
|
bundle.getString("leader"),
|
||||||
|
"party",
|
||||||
|
bundle.getString("privacy"),
|
||||||
|
bundle.getBoolean("leaderCreateChallenge"))
|
||||||
|
.flatMap {
|
||||||
|
userRepository.retrieveUser(false)
|
||||||
|
}
|
||||||
|
.subscribe(Consumer {
|
||||||
|
}, RxErrorHandler.handleEmptyError())
|
||||||
|
} else {
|
||||||
|
this.socialRepository.updateGroup(this.group,
|
||||||
|
bundle?.getString("name"),
|
||||||
|
bundle?.getString("description"),
|
||||||
|
bundle?.getString("leader"),
|
||||||
|
bundle?.getBoolean("leaderCreateChallenge"))
|
||||||
|
.subscribe(Consumer { }, RxErrorHandler.handleEmptyError())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun refresh() {
|
private fun refresh() {
|
||||||
if (group != null) {
|
if (group != null) {
|
||||||
compositeSubscription.add(socialRepository.retrieveGroup(group?.id ?: "").subscribe(Consumer {}, RxErrorHandler.handleEmptyError()))
|
compositeSubscription.add(socialRepository.retrieveGroup(group?.id ?: "").subscribe(Consumer {}, RxErrorHandler.handleEmptyError()))
|
||||||
|
|
|
||||||
|
|
@ -180,11 +180,13 @@ class GuildFragment : BaseMainFragment() {
|
||||||
|
|
||||||
private fun displayEditForm() {
|
private fun displayEditForm() {
|
||||||
val bundle = Bundle()
|
val bundle = Bundle()
|
||||||
bundle.putString("groupID", this.guild?.id)
|
bundle.putString("groupID", guild?.id)
|
||||||
bundle.putString("name", this.guild?.name)
|
bundle.putString("name", guild?.name)
|
||||||
bundle.putString("description", this.guild?.description)
|
bundle.putString("description", guild?.description)
|
||||||
bundle.putString("privacy", this.guild?.privacy)
|
bundle.putString("privacy", guild?.privacy)
|
||||||
bundle.putString("leader", this.guild?.leaderID)
|
bundle.putString("leader", guild?.leaderID)
|
||||||
|
bundle.putBoolean("leaderCreateChallenge", guild?.leaderOnlyChallenges ?: true)
|
||||||
|
|
||||||
|
|
||||||
val intent = Intent(activity, GroupFormActivity::class.java)
|
val intent = Intent(activity, GroupFormActivity::class.java)
|
||||||
intent.putExtras(bundle)
|
intent.putExtras(bundle)
|
||||||
|
|
@ -202,7 +204,7 @@ class GuildFragment : BaseMainFragment() {
|
||||||
bundle?.getString("name"),
|
bundle?.getString("name"),
|
||||||
bundle?.getString("description"),
|
bundle?.getString("description"),
|
||||||
bundle?.getString("leader"),
|
bundle?.getString("leader"),
|
||||||
bundle?.getString("privacy"))
|
bundle?.getBoolean("leaderCreateChallenge"))
|
||||||
.subscribe(Consumer { }, RxErrorHandler.handleEmptyError())
|
.subscribe(Consumer { }, RxErrorHandler.handleEmptyError())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -195,7 +195,7 @@ class PartyDetailFragment constructor(private val viewModel: PartyViewModel) : B
|
||||||
val builder = AlertDialog.Builder(activity)
|
val builder = AlertDialog.Builder(activity)
|
||||||
.setMessage(R.string.leave_party_confirmation)
|
.setMessage(R.string.leave_party_confirmation)
|
||||||
.setPositiveButton(R.string.yes) { _, _ ->
|
.setPositiveButton(R.string.yes) { _, _ ->
|
||||||
viewModel.leaveGroup { activity?.supportFragmentManager?.beginTransaction()?.remove(this)?.commit() }
|
viewModel.leaveGroup { }
|
||||||
}.setNegativeButton(R.string.no) { _, _ -> }
|
}.setNegativeButton(R.string.no) { _, _ -> }
|
||||||
builder.show()
|
builder.show()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,8 +12,7 @@ import androidx.lifecycle.ViewModelProviders
|
||||||
import androidx.viewpager.widget.ViewPager
|
import androidx.viewpager.widget.ViewPager
|
||||||
import com.habitrpg.android.habitica.R
|
import com.habitrpg.android.habitica.R
|
||||||
import com.habitrpg.android.habitica.components.AppComponent
|
import com.habitrpg.android.habitica.components.AppComponent
|
||||||
import com.habitrpg.android.habitica.extensions.notNull
|
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||||
import com.habitrpg.android.habitica.helpers.RemoteConfigManager
|
|
||||||
import com.habitrpg.android.habitica.models.social.Group
|
import com.habitrpg.android.habitica.models.social.Group
|
||||||
import com.habitrpg.android.habitica.ui.activities.GroupFormActivity
|
import com.habitrpg.android.habitica.ui.activities.GroupFormActivity
|
||||||
import com.habitrpg.android.habitica.ui.activities.PartyInviteActivity
|
import com.habitrpg.android.habitica.ui.activities.PartyInviteActivity
|
||||||
|
|
@ -24,15 +23,14 @@ import com.habitrpg.android.habitica.ui.helpers.bindView
|
||||||
import com.habitrpg.android.habitica.ui.helpers.resetViews
|
import com.habitrpg.android.habitica.ui.helpers.resetViews
|
||||||
import com.habitrpg.android.habitica.ui.viewmodels.GroupViewType
|
import com.habitrpg.android.habitica.ui.viewmodels.GroupViewType
|
||||||
import com.habitrpg.android.habitica.ui.viewmodels.PartyViewModel
|
import com.habitrpg.android.habitica.ui.viewmodels.PartyViewModel
|
||||||
|
import io.reactivex.functions.Consumer
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import javax.inject.Inject
|
|
||||||
|
|
||||||
class PartyFragment : BaseMainFragment() {
|
class PartyFragment : BaseMainFragment() {
|
||||||
|
|
||||||
@Inject
|
|
||||||
lateinit var configRepository: RemoteConfigManager
|
|
||||||
|
|
||||||
private val viewPager: ViewPager? by bindView(R.id.viewPager)
|
private val viewPager: ViewPager? by bindView(R.id.viewPager)
|
||||||
|
private var firstFragment: Fragment? = null
|
||||||
private var partyMemberListFragment: PartyMemberListFragment? = null
|
private var partyMemberListFragment: PartyMemberListFragment? = null
|
||||||
private var chatFragment: ChatFragment? = null
|
private var chatFragment: ChatFragment? = null
|
||||||
private var viewPagerAdapter: androidx.fragment.app.FragmentPagerAdapter? = null
|
private var viewPagerAdapter: androidx.fragment.app.FragmentPagerAdapter? = null
|
||||||
|
|
@ -62,10 +60,26 @@ class PartyFragment : BaseMainFragment() {
|
||||||
|
|
||||||
viewModel.loadPartyID()
|
viewModel.loadPartyID()
|
||||||
|
|
||||||
// Get the full group data
|
compositeSubscription.add(userRepository.getUser()
|
||||||
if (userHasParty()) {
|
.map {
|
||||||
viewModel.retrieveGroup {}
|
it.hasParty()
|
||||||
}
|
}
|
||||||
|
.distinctUntilChanged()
|
||||||
|
.subscribe(Consumer {
|
||||||
|
val fragment = firstFragment
|
||||||
|
if (fragment != null) {
|
||||||
|
childFragmentManager.beginTransaction().remove(fragment).commit()
|
||||||
|
}
|
||||||
|
viewPager?.adapter?.notifyDataSetChanged()
|
||||||
|
|
||||||
|
if (it) {
|
||||||
|
viewModel.retrieveGroup {}
|
||||||
|
tabLayout?.visibility = View.VISIBLE
|
||||||
|
} else {
|
||||||
|
tabLayout?.visibility = View.GONE
|
||||||
|
}
|
||||||
|
|
||||||
|
}, RxErrorHandler.handleEmptyError()))
|
||||||
|
|
||||||
viewPager?.currentItem = 0
|
viewPager?.currentItem = 0
|
||||||
|
|
||||||
|
|
@ -74,10 +88,6 @@ class PartyFragment : BaseMainFragment() {
|
||||||
this.tutorialText = getString(R.string.tutorial_party)
|
this.tutorialText = getString(R.string.tutorial_party)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun userHasParty(): Boolean {
|
|
||||||
return user?.party?.id?.isNotEmpty() == true
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun injectFragment(component: AppComponent) {
|
override fun injectFragment(component: AppComponent) {
|
||||||
component.inject(this)
|
component.inject(this)
|
||||||
}
|
}
|
||||||
|
|
@ -102,6 +112,9 @@ class PartyFragment : BaseMainFragment() {
|
||||||
if (group != null && this.user != null) {
|
if (group != null && this.user != null) {
|
||||||
if (group.leaderID == this.user?.id) {
|
if (group.leaderID == this.user?.id) {
|
||||||
inflater.inflate(R.menu.menu_party_admin, menu)
|
inflater.inflate(R.menu.menu_party_admin, menu)
|
||||||
|
if (group.memberCount > 1) {
|
||||||
|
menu.findItem(R.id.menu_guild_leave).isVisible = false
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
inflater.inflate(R.menu.menu_party, menu)
|
inflater.inflate(R.menu.menu_party, menu)
|
||||||
}
|
}
|
||||||
|
|
@ -128,9 +141,6 @@ class PartyFragment : BaseMainFragment() {
|
||||||
.setMessage(context?.getString(R.string.leave_party_confirmation))
|
.setMessage(context?.getString(R.string.leave_party_confirmation))
|
||||||
.setPositiveButton(context?.getString(R.string.yes)) { _, _ ->
|
.setPositiveButton(context?.getString(R.string.yes)) { _, _ ->
|
||||||
viewModel.leaveGroup {
|
viewModel.leaveGroup {
|
||||||
parentFragment.notNull { fragment ->
|
|
||||||
activity?.supportFragmentManager?.beginTransaction()?.remove(fragment)?.commit()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.setNegativeButton(context?.getString(R.string.no)) { dialog, _ -> dialog.dismiss() }
|
.setNegativeButton(context?.getString(R.string.no)) { dialog, _ -> dialog.dismiss() }
|
||||||
|
|
@ -147,8 +157,10 @@ class PartyFragment : BaseMainFragment() {
|
||||||
val group = viewModel.getGroupData().value
|
val group = viewModel.getGroupData().value
|
||||||
bundle.putString("groupID", group?.id)
|
bundle.putString("groupID", group?.id)
|
||||||
bundle.putString("name", group?.name)
|
bundle.putString("name", group?.name)
|
||||||
|
bundle.putString("groupType", group?.type)
|
||||||
bundle.putString("description", group?.description)
|
bundle.putString("description", group?.description)
|
||||||
bundle.putString("leader", group?.leaderID)
|
bundle.putString("leader", group?.leaderID)
|
||||||
|
bundle.putBoolean("leaderCreateChallenge", group?.leaderOnlyChallenges ?: false)
|
||||||
|
|
||||||
val intent = Intent(activity, GroupFormActivity::class.java)
|
val intent = Intent(activity, GroupFormActivity::class.java)
|
||||||
intent.putExtras(bundle)
|
intent.putExtras(bundle)
|
||||||
|
|
@ -161,7 +173,7 @@ class PartyFragment : BaseMainFragment() {
|
||||||
when (requestCode) {
|
when (requestCode) {
|
||||||
GroupFormActivity.GROUP_FORM_ACTIVITY -> {
|
GroupFormActivity.GROUP_FORM_ACTIVITY -> {
|
||||||
if (resultCode == Activity.RESULT_OK) {
|
if (resultCode == Activity.RESULT_OK) {
|
||||||
viewModel.updateGroup(data?.extras)
|
viewModel.updateOrCreateGroup(data?.extras)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PartyInviteActivity.RESULT_SEND_INVITES -> {
|
PartyInviteActivity.RESULT_SEND_INVITES -> {
|
||||||
|
|
@ -201,18 +213,19 @@ class PartyFragment : BaseMainFragment() {
|
||||||
override fun getItem(position: Int): androidx.fragment.app.Fragment {
|
override fun getItem(position: Int): androidx.fragment.app.Fragment {
|
||||||
return when (position) {
|
return when (position) {
|
||||||
0 -> {
|
0 -> {
|
||||||
if (user?.hasParty() == true) {
|
firstFragment = if (user?.hasParty() == true) {
|
||||||
val detailFragment = PartyDetailFragment(viewModel)
|
val detailFragment = PartyDetailFragment(viewModel)
|
||||||
detailFragment
|
detailFragment
|
||||||
} else {
|
} else {
|
||||||
GroupInformationFragment.newInstance(null, user)
|
GroupInformationFragment.newInstance(null, user)
|
||||||
}
|
}
|
||||||
|
firstFragment
|
||||||
}
|
}
|
||||||
1 -> {
|
1 -> {
|
||||||
if (chatFragment == null) {
|
if (chatFragment == null) {
|
||||||
chatFragment = ChatFragment(viewModel)
|
chatFragment = ChatFragment(viewModel)
|
||||||
}
|
}
|
||||||
chatFragment ?: Fragment()
|
chatFragment
|
||||||
}
|
}
|
||||||
2 -> {
|
2 -> {
|
||||||
if (partyMemberListFragment == null) {
|
if (partyMemberListFragment == null) {
|
||||||
|
|
@ -221,15 +234,15 @@ class PartyFragment : BaseMainFragment() {
|
||||||
partyMemberListFragment?.setPartyId(user?.party?.id ?: "")
|
partyMemberListFragment?.setPartyId(user?.party?.id ?: "")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
partyMemberListFragment ?: Fragment()
|
partyMemberListFragment
|
||||||
}
|
}
|
||||||
else -> Fragment()
|
else -> Fragment()
|
||||||
}
|
} ?: Fragment()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getCount(): Int {
|
override fun getCount(): Int {
|
||||||
return if (viewModel.getGroupData().value == null) {
|
return if (user?.hasParty() != true) {
|
||||||
1
|
1
|
||||||
} else {
|
} else {
|
||||||
3
|
3
|
||||||
|
|
@ -244,6 +257,14 @@ class PartyFragment : BaseMainFragment() {
|
||||||
else -> ""
|
else -> ""
|
||||||
} ?: ""
|
} ?: ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun getItemPosition(fragment: Any): Int {
|
||||||
|
return if ((fragment is GroupInformationFragment && user?.hasParty() == true) || (fragment is PartyDetailFragment && user?.hasParty() != true)) {
|
||||||
|
POSITION_NONE
|
||||||
|
} else {
|
||||||
|
POSITION_UNCHANGED
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
this.viewPager?.adapter = viewPagerAdapter
|
this.viewPager?.adapter = viewPagerAdapter
|
||||||
|
|
||||||
|
|
@ -266,6 +287,4 @@ class PartyFragment : BaseMainFragment() {
|
||||||
})
|
})
|
||||||
tabLayout?.setupWithViewPager(viewPager)
|
tabLayout?.setupWithViewPager(viewPager)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ class AutocompleteAdapter(val context: Context, val socialRepository: SocialRepo
|
||||||
override fun performFiltering(constraint: CharSequence?): FilterResults {
|
override fun performFiltering(constraint: CharSequence?): FilterResults {
|
||||||
val filterResults = FilterResults()
|
val filterResults = FilterResults()
|
||||||
if (constraint != null && constraint.isNotEmpty()) {
|
if (constraint != null && constraint.isNotEmpty()) {
|
||||||
if (constraint[0] == '@' && socialRepository != null) {
|
if (constraint[0] == '@' && constraint.length >= 3 && socialRepository != null) {
|
||||||
isAutocompletingUsers = true
|
isAutocompletingUsers = true
|
||||||
userResults = socialRepository.findUsernames(constraint.toString().drop(1), autocompleteContext, groupID).blockingFirst(arrayListOf())
|
userResults = socialRepository.findUsernames(constraint.toString().drop(1), autocompleteContext, groupID).blockingFirst(arrayListOf())
|
||||||
filterResults.values = userResults
|
filterResults.values = userResults
|
||||||
|
|
|
||||||
|
|
@ -89,15 +89,23 @@ open class GroupViewModel: BaseViewModel() {
|
||||||
.subscribe(Consumer { }, RxErrorHandler.handleEmptyError()))
|
.subscribe(Consumer { }, RxErrorHandler.handleEmptyError()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun updateGroup(bundle: Bundle?) {
|
|
||||||
|
|
||||||
|
fun updateOrCreateGroup(bundle: Bundle?) {
|
||||||
if (group.value == null) {
|
if (group.value == null) {
|
||||||
return
|
socialRepository.createGroup(bundle?.getString("name"),
|
||||||
|
bundle?.getString("description"),
|
||||||
|
bundle?.getString("leader"),
|
||||||
|
bundle?.getString("groupType"),
|
||||||
|
bundle?.getString("privacy"),
|
||||||
|
bundle?.getBoolean("leaderCreateChallenge"))
|
||||||
|
} else {
|
||||||
|
disposable.add(socialRepository.updateGroup(group.value, bundle?.getString("name"),
|
||||||
|
bundle?.getString("description"),
|
||||||
|
bundle?.getString("leader"),
|
||||||
|
bundle?.getBoolean("leaderCreateChallenge"))
|
||||||
|
.subscribe(Consumer { }, RxErrorHandler.handleEmptyError()))
|
||||||
}
|
}
|
||||||
disposable.add(socialRepository.updateGroup(group.value, bundle?.getString("name"),
|
|
||||||
bundle?.getString("description"),
|
|
||||||
bundle?.getString("leader"),
|
|
||||||
bundle?.getString("privacy"))
|
|
||||||
.subscribe(Consumer { }, RxErrorHandler.handleEmptyError()))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun leaveGroup(function: () -> Unit) {
|
fun leaveGroup(function: () -> Unit) {
|
||||||
|
|
@ -148,10 +156,13 @@ open class GroupViewModel: BaseViewModel() {
|
||||||
}
|
}
|
||||||
|
|
||||||
fun retrieveGroupChat(onComplete: () -> Unit) {
|
fun retrieveGroupChat(onComplete: () -> Unit) {
|
||||||
groupIDSubject.value?.value.notNull {
|
val groupID = groupIDSubject.value?.value
|
||||||
disposable.add(socialRepository.retrieveGroupChat(it).subscribe(Consumer {
|
if (groupID.isNullOrEmpty()) {
|
||||||
onComplete()
|
onComplete()
|
||||||
}, RxErrorHandler.handleEmptyError()))
|
return
|
||||||
}
|
}
|
||||||
|
disposable.add(socialRepository.retrieveGroupChat(groupID).subscribe(Consumer {
|
||||||
|
onComplete()
|
||||||
|
}, RxErrorHandler.handleEmptyError()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -106,6 +106,16 @@ class GroupSerialization : JsonDeserializer<Group>, JsonSerializer<Group> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (obj.has("leaderOnly")) {
|
||||||
|
val leaderOnly = obj.getAsJsonObject("leaderOnly")
|
||||||
|
if (leaderOnly.has("challenges")) {
|
||||||
|
group.leaderOnlyChallenges = leaderOnly.get("challenges").asBoolean
|
||||||
|
}
|
||||||
|
if (leaderOnly.has("getGems")) {
|
||||||
|
group.leaderOnlyGetGems = leaderOnly.get("getGems").asBoolean
|
||||||
|
}
|
||||||
|
}
|
||||||
return group
|
return group
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -118,6 +128,10 @@ class GroupSerialization : JsonDeserializer<Group>, JsonSerializer<Group> {
|
||||||
obj.addProperty("type", src.type)
|
obj.addProperty("type", src.type)
|
||||||
obj.addProperty("type", src.type)
|
obj.addProperty("type", src.type)
|
||||||
obj.addProperty("leader", src.leaderID)
|
obj.addProperty("leader", src.leaderID)
|
||||||
|
val leaderOnly = JsonObject()
|
||||||
|
leaderOnly.addProperty("challenges", src.leaderOnlyChallenges)
|
||||||
|
leaderOnly.addProperty("getGems", src.leaderOnlyGetGems)
|
||||||
|
obj.add("leaderOnly", leaderOnly)
|
||||||
return obj
|
return obj
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue