diff --git a/Habitica/res/layout/fragment_no_party.xml b/Habitica/res/layout/fragment_no_party.xml index 58d0ae609..ff4baa7f2 100644 --- a/Habitica/res/layout/fragment_no_party.xml +++ b/Habitica/res/layout/fragment_no_party.xml @@ -85,21 +85,14 @@ android:layout_marginTop="@dimen/spacing_large"/> - - - + android:paddingBottom="60dp" + app:cardBackgroundColor="@color/window_background"> - + - diff --git a/Habitica/res/layout/shop_armoire_gear.xml b/Habitica/res/layout/shop_armoire_gear.xml index f72adffa0..9e375e00b 100644 --- a/Habitica/res/layout/shop_armoire_gear.xml +++ b/Habitica/res/layout/shop_armoire_gear.xml @@ -3,6 +3,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" android:orientation="vertical" android:background="@drawable/layout_rounded_bg_window" android:layout_marginHorizontal="12dp" @@ -35,13 +36,17 @@ diff --git a/Habitica/res/layout/shop_section_header.xml b/Habitica/res/layout/shop_section_header.xml index 25bab857a..8d4d5248c 100644 --- a/Habitica/res/layout/shop_section_header.xml +++ b/Habitica/res/layout/shop_section_header.xml @@ -70,9 +70,10 @@ style="@style/Body1" android:layout_marginBottom="1dp"/> diff --git a/Habitica/res/navigation/navigation.xml b/Habitica/res/navigation/navigation.xml index d25a6780f..bd526b888 100644 --- a/Habitica/res/navigation/navigation.xml +++ b/Habitica/res/navigation/navigation.xml @@ -69,8 +69,8 @@ + android:name="com.habitrpg.android.habitica.ui.fragments.social.party.PartySeekingFragment" + android:label="@string/find_more_members"> Renunciando ¿Estás seguro de que quieres ser un %s\? ¡Ahora eres un %s! - ¡Tienes nuevo Equipamiento de Combate predeterminado que puedes cambiar en Equipo! + Elegir Clase Volver Atrás ¿Estás seguro de que quieres renunciar\? @@ -905,4 +905,4 @@ Siguiente Reloj de Arena Tienes que formar parte de un Grupo antes de comenzar una misión ¿Estás seguro de que quieres reiniciar\? - \ No newline at end of file + diff --git a/Habitica/res/values-bg/strings.xml b/Habitica/res/values-bg/strings.xml index 414edaa1a..98d00837d 100644 --- a/Habitica/res/values-bg/strings.xml +++ b/Habitica/res/values-bg/strings.xml @@ -233,7 +233,7 @@ Отказване Наистина ли искате да бъдете %s? Вие вече сте %s! - Вече имате ново бойно снаряжение по подразбиране, което можете да намерите в „Екипировка“! + Избиране на класа Назад Наистина ли искате да се откажете? @@ -647,4 +647,4 @@ %1$s]]> %1$s]]> %1$s]]> - \ No newline at end of file + diff --git a/Habitica/res/values-ca/strings.xml b/Habitica/res/values-ca/strings.xml index 3cda15ea3..f7ac02316 100755 --- a/Habitica/res/values-ca/strings.xml +++ b/Habitica/res/values-ca/strings.xml @@ -183,7 +183,7 @@ No optar per res Segur que vols ser un %s? Ara ets un %s! - Tens un nou Equip de Batalla per defecte que pots canviar a Equipament. + Escull la classe Torna enrere Estàs segur que no vols optar per res? @@ -278,4 +278,4 @@ Obrir Has guanyat un/a %1$s com a recompensa per a la teva devoció per millorar la teva vida. El pròxim premi es desbloquejarà d\'aquí a %1$d inicis de sessió - \ No newline at end of file + diff --git a/Habitica/res/values-cs/strings.xml b/Habitica/res/values-cs/strings.xml index b59278ade..f60f96322 100755 --- a/Habitica/res/values-cs/strings.xml +++ b/Habitica/res/values-cs/strings.xml @@ -212,7 +212,7 @@ Neúčastnit se Opravdu chceš být %s? Nyní jsi %s! - Máš novou výchozí Bojovou výzbroj, kterou si můžeš změnit ve Vybavení! + Vybrat třidu Jít zpět Jsi si jist, že se chceš neúčastnit? @@ -494,4 +494,4 @@ Nemáte dostatek drahokamů k vytvoření výzvy. Dejte své výzvě krátké a výstižné jméno K vytvoření této výzvy potřebujete zvolit jméno. - \ No newline at end of file + diff --git a/Habitica/res/values-de/strings.xml b/Habitica/res/values-de/strings.xml index 72e5b8d93..cc29b84cb 100644 --- a/Habitica/res/values-de/strings.xml +++ b/Habitica/res/values-de/strings.xml @@ -232,7 +232,7 @@ Später entscheiden Bist Du sicher, dass Du %s werden willst? Du bist jetzt ein/eine %s! - Du hast neue Basis-Kampfausrüstung, die Du im Ausrüstungsreiter wechseln kannst! + Klasse wählen Zurück Bist Du sicher, dass Du Dich noch nicht entscheiden willst? @@ -1265,4 +1265,4 @@ Die Quest-Schriftrolle wird an den Quest-Besitzer zurückgegeben. Du Du und %d andere - \ No newline at end of file + diff --git a/Habitica/res/values-en-rGB/strings.xml b/Habitica/res/values-en-rGB/strings.xml index 1599fc882..8af2b2f63 100644 --- a/Habitica/res/values-en-rGB/strings.xml +++ b/Habitica/res/values-en-rGB/strings.xml @@ -213,7 +213,7 @@ Opt Out Are you sure you want to be a %s? You are now a %s! - You have new default Battle Gear that you can change under Equipment! + Choose Class Go Back Are you sure you want to Opt Out? @@ -1053,4 +1053,4 @@ Between October 29th and November 2nd, simply purchase any Gem bundle like usual and your account will be credited with the promotional amount of Gems. More Gems to spend, share, or save for any future releases! View Gem Bundles The Fall Gala is in full swing so we thought it was the perfect time for a Gem Sale! Now you will get more Gems with each purchase than ever before. - \ No newline at end of file + diff --git a/Habitica/res/values-es/strings.xml b/Habitica/res/values-es/strings.xml index 41e189102..9bc99991f 100644 --- a/Habitica/res/values-es/strings.xml +++ b/Habitica/res/values-es/strings.xml @@ -233,7 +233,7 @@ No elegir ¿Seguro que quieres ser %s? ¡Ahora eres un %s! - ¡Tienes un nuevo Equipo de Combate que puedes ponerte en tu Equipamiento! + Elegir clase Volver ¿Seguro que no quieres elegir? @@ -1142,4 +1142,4 @@ Ahora estás suscrito por %s meses Ganaste %s gemas. Equipo de %s - \ No newline at end of file + diff --git a/Habitica/res/values-fr/strings.xml b/Habitica/res/values-fr/strings.xml index f17136001..ee1e6275a 100644 --- a/Habitica/res/values-fr/strings.xml +++ b/Habitica/res/values-fr/strings.xml @@ -232,7 +232,7 @@ Désactiver Êtes vous sûr de vouloir devenir un %s \? Vous êtes maintenant un %s ! - Vous avez une nouvelle tenue de combat par défaut que vous pouvez changer dans l\'équipement ! + Choisissez une classe Revenir Confirmez-vous vouloir désactiver votre compte ? @@ -1263,4 +1263,4 @@ %d personne %d personnes - \ No newline at end of file + diff --git a/Habitica/res/values-hr-rHR/strings.xml b/Habitica/res/values-hr-rHR/strings.xml index b18e35513..4571c240c 100644 --- a/Habitica/res/values-hr-rHR/strings.xml +++ b/Habitica/res/values-hr-rHR/strings.xml @@ -232,7 +232,7 @@ Izaberi kasnije Jesi li siguran/na da želiš biti %s? Sada si %s! - Imaš novu zadanu Ratnu Opremu koju možeš promijeniti pod Opremom! + Odaberi Klasu Idi natrag Jesi li siguran/na da želiš izabrati kasnije? @@ -1140,4 +1140,4 @@ Vrste popisa zadataka Kompaktno Minimalno - \ No newline at end of file + diff --git a/Habitica/res/values-in/strings.xml b/Habitica/res/values-in/strings.xml index be762b675..d911c2b87 100644 --- a/Habitica/res/values-in/strings.xml +++ b/Habitica/res/values-in/strings.xml @@ -220,7 +220,7 @@ Matikan Fitur Apakah kamu yakin ingin menjadi seorang %s? Kamu sekarang seorang %s! - Kamu memiliki Baju Perang baru yang dapat diganti pada menu Perlengkapan! + Pilih Kelas Kembali Apakah kamu yakin kamu ingin mematikan fitur? @@ -959,4 +959,4 @@ Kamu mengobrak-abrik isi Peti dan menemukan makanan. Kenapa bisa ada di sini\? Jual Buat party baru - \ No newline at end of file + diff --git a/Habitica/res/values-it/strings.xml b/Habitica/res/values-it/strings.xml index 0227734e8..91c03e85e 100644 --- a/Habitica/res/values-it/strings.xml +++ b/Habitica/res/values-it/strings.xml @@ -232,7 +232,7 @@ Rinuncia Vuoi davvero essere un %s? Ora sei un %s! - Hai del nuovo equipaggiamento da battaglia che puoi indossare, vai nella sezione Equipaggiamento! + Scegli classe Ritorna Vuoi davvero rinunciare? @@ -1260,4 +1260,4 @@ Tu Voi, %d altri - \ No newline at end of file + diff --git a/Habitica/res/values-ja/strings.xml b/Habitica/res/values-ja/strings.xml index 93dcb9d99..d93f3447e 100644 --- a/Habitica/res/values-ja/strings.xml +++ b/Habitica/res/values-ja/strings.xml @@ -232,7 +232,7 @@ 選ばない %s になります。いいですか? あなたは%s に転職した! - 新たな標準の武装を手に入れました。「装備」で取り換えることもできます! + クラスを選ぶ 戻る 選ばないでいい? @@ -1261,4 +1261,4 @@ あなたと他 %d - \ No newline at end of file + diff --git a/Habitica/res/values-ko/strings.xml b/Habitica/res/values-ko/strings.xml index fa90c3b5a..87ec43833 100644 --- a/Habitica/res/values-ko/strings.xml +++ b/Habitica/res/values-ko/strings.xml @@ -220,7 +220,7 @@ 선택 유예 %s 이(가) 되고싶은 것이 확실한가요\? %s이(가) 되었습니다! - 장비 메뉴에서 교체할 수 있는 새로운 기본 전투 장비를 얻었습니다! + 직업 선택 뒤로 가기 선택을 유예하고 싶은 것이 확실한가요? @@ -1259,4 +1259,4 @@ 공유 중인 과제 복사 그룹 계획 설정 할당된 과제와 열려 있는 과제를 개인 과제 목록에 표시 - \ No newline at end of file + diff --git a/Habitica/res/values-lt/strings.xml b/Habitica/res/values-lt/strings.xml index 962bebe49..3d4022dbe 100644 --- a/Habitica/res/values-lt/strings.xml +++ b/Habitica/res/values-lt/strings.xml @@ -292,7 +292,7 @@ Warriors surinko daugiau ir geresnių kritinių paspaudimų, kurie atsitiktinai suteikia premiją „Gold“, „Experience“ ir „drop“ šansams atlikti užduotį. Jie taip pat susiduria su sunkia boso monstrų žala. Žaisti Warrior, jei radote motyvaciją iš neprognozuojamų jackpoto stiliaus apdovanojimų, arba norėsite išvalyti skausmą bosas Quests! Atsisakymas Dabar esate %s! - Turite naują numatytąjį „Battle Gear“, kurį galite keisti pagal „Įranga“! + Pakeiskite savo klasę ir grąžinkite savo statistinius taškus už 3 brangakmenius. Jei turite draugų, kurie jau naudojasi Habitica, pakvieskite juos pagal vartotojo vardą. Habiticoje pasiekiau %d lygį, gerindamas savo tikrojo gyvenimo įpročius! @@ -352,4 +352,4 @@ Užsisakydami gaunate šias naudingas išmokas: Prenumeratos būsena Palikite iššūkį - \ No newline at end of file + diff --git a/Habitica/res/values-nl/strings.xml b/Habitica/res/values-nl/strings.xml index 2c83f649a..d06059989 100644 --- a/Habitica/res/values-nl/strings.xml +++ b/Habitica/res/values-nl/strings.xml @@ -233,7 +233,7 @@ Afmelden Weet je zeker dat je een %s wilt zijn? Je bent nu een %s! - Je hebt een nieuwe standaard gevechtsuitrusting die je kan veranderen onder Uitrusting! + Kies een Klasse Ga terug Weet je zeker dat je je wil afmelden? @@ -994,4 +994,4 @@ Mystieke zandlopers zijn een zeldzaam soort betaalmiddel dat je alleen ontvangt bij een abonnement op Habitica dat minstens drie opeenvolgende maanden duurt. Je kunt er in de Tijdreiziger\'s winkel voorafgaande uitrustingssets, huisdieren, rijdieren, geanimeerde acthergronden of zelfs speciale queestes voor kopen. \n \nJe kunt maximaal vier mystieke zandlopers per jaar ontvangen. Het tijdstip dat je ze krijgt hangt af van wanneer je abonnement wordt herniewd. Ze worden uitgezonden op de eerste dag van een nieuwe maand nadat je laatste abonnementsbetaling je heeft gequalificeerd voor een zandloper. Zie de [Abonnementen]-pagina voor meer details. - \ No newline at end of file + diff --git a/Habitica/res/values-no/strings.xml b/Habitica/res/values-no/strings.xml index e893428f0..679319234 100755 --- a/Habitica/res/values-no/strings.xml +++ b/Habitica/res/values-no/strings.xml @@ -202,7 +202,7 @@ Reserver Deg Er du sikker på at du vil være en %s? Du er nå en %s! - Du har nytt standard stridsutstyr som du kan bytte til under Utstyr! + Velg Klasse Gå Tilbake Er du sikker på at du vil reservere deg? @@ -417,4 +417,4 @@ Endre e-post adresse Endre Styrke - \ No newline at end of file + diff --git a/Habitica/res/values-pl/strings.xml b/Habitica/res/values-pl/strings.xml index b23a19a5a..4c54dc76e 100644 --- a/Habitica/res/values-pl/strings.xml +++ b/Habitica/res/values-pl/strings.xml @@ -223,7 +223,7 @@ Wycofaj się Jesteś pewien, że chcesz być %s? Jesteś teraz %s! - Masz nowe domyślne wyposażenie bojowe, które możesz zmienić pod Wyposażeniem! + Wybierz klasę postaci Wróć Czy na pewno chcesz wyjść? @@ -781,4 +781,4 @@ Dostępne dla %s Niezapisane zmiany Jesteś pewien, że chcesz porzucić zmiany w tym zadaniu\? - \ No newline at end of file + diff --git a/Habitica/res/values-pt-rBR/strings.xml b/Habitica/res/values-pt-rBR/strings.xml index b70b5b9d9..7dfc67fcd 100644 --- a/Habitica/res/values-pt-rBR/strings.xml +++ b/Habitica/res/values-pt-rBR/strings.xml @@ -232,7 +232,7 @@ Decidir mais tarde Você tem certeza que quer ser um(a) %s\? Você é um(a) %s agora! - Você tem um novo Equipamento de Batalha padrão, que pode ser trocado em Equipamentos! + Escolha a sua Classe Voltar Você tem certeza de que ainda não quer escolher\? @@ -1262,4 +1262,4 @@ Você Vocês, %d outros - \ No newline at end of file + diff --git a/Habitica/res/values-pt-rPT/strings.xml b/Habitica/res/values-pt-rPT/strings.xml index 2724d0de4..40b7afee0 100644 --- a/Habitica/res/values-pt-rPT/strings.xml +++ b/Habitica/res/values-pt-rPT/strings.xml @@ -364,7 +364,7 @@ \n • Seus itens de missão de dano ou coleta de chefe permanecerão pendentes até o check-out Guerreiros obtêm mais Golpes Críticos e infligem maior dano aos Monstros. Joga como Guerreiro se quiseres derrotar Monstros mais facilmente! Guerreiros beneficiam de uma elevada estatística de Força. Optando por - Você tem um novo Battle Gear padrão que pode ser alterado em Equipamento! + Mude sua classe e devolva seus pontos de status por 3 gemas. Notificações Já sabes tudo o que se passa! @@ -718,4 +718,4 @@ Usar item em membro de equipa> Alterações não gravadas Tens a certeza de que queres descartar as alterações nesta tarefa\? - \ No newline at end of file + diff --git a/Habitica/res/values-ro/strings.xml b/Habitica/res/values-ro/strings.xml index e5fb00f96..8b7beabd5 100755 --- a/Habitica/res/values-ro/strings.xml +++ b/Habitica/res/values-ro/strings.xml @@ -208,7 +208,7 @@ Alege să nu iei parte Ești sigur că vrei să fii %s? De acum ești %s! - Acum ai Echipament de Luptă de bază, pe care îl poți schimba de la Echipament! + Alege Clasa Mergi înapoi Ești sigur că vrei să nu iei parte? @@ -509,4 +509,4 @@ Ian Ghidul Expedițiilor Vrăjitoarea Sezonului Atac furios: - \ No newline at end of file + diff --git a/Habitica/res/values-ru/strings.xml b/Habitica/res/values-ru/strings.xml index 1ccf4418b..956e4b4f7 100644 --- a/Habitica/res/values-ru/strings.xml +++ b/Habitica/res/values-ru/strings.xml @@ -230,7 +230,7 @@ Отказаться Вы уверены, что хотите продолжить как %s\? Теперь вы %s! - У вас есть новая боевая экипировка по умолчанию, которую вы можете сменить в разделе Снаряжение! + Выбрать класс Вернуться назад Вы уверены, что хотите отказаться? @@ -1266,4 +1266,4 @@ - \ No newline at end of file + diff --git a/Habitica/res/values-sv/strings.xml b/Habitica/res/values-sv/strings.xml index eea1421ba..2ddbed534 100755 --- a/Habitica/res/values-sv/strings.xml +++ b/Habitica/res/values-sv/strings.xml @@ -202,7 +202,7 @@ Välj bort Är du säker på att du vill vara en %s? Du är nu en %s! - Du har ny standard Stridsutrustning som du kan ändra under Utrustning! + Välj klass Gå tillbaka Är du säker på att du vill välja bort? @@ -634,4 +634,4 @@ Ägar Egenskapsfördelning Erfarenhetspoäng - \ No newline at end of file + diff --git a/Habitica/res/values-tr/strings.xml b/Habitica/res/values-tr/strings.xml index bfd39404b..3f4185c37 100644 --- a/Habitica/res/values-tr/strings.xml +++ b/Habitica/res/values-tr/strings.xml @@ -233,7 +233,7 @@ Çekil Bir %s olmak istediğine emin misin? Yeni sınıfın: %s! - Ekipmanlar menüsü altında değiştirebileceğin yeni varsayılan Savaş Ekipmanın var! + Sınıf Seç Geri Dön Çekilmek istediğinden emin misin? @@ -1151,4 +1151,4 @@ Kazanan olarak seçildiniz! Zaferiniz Başarımlarınıza kaydedildi. Davet edilmedikçe bu Takıma tekrar katılamazsınız. Bir Meydan Okuma kazandınız - \ No newline at end of file + diff --git a/Habitica/res/values-uk/strings.xml b/Habitica/res/values-uk/strings.xml index 4e5aa8365..42d9bd0fa 100755 --- a/Habitica/res/values-uk/strings.xml +++ b/Habitica/res/values-uk/strings.xml @@ -296,7 +296,7 @@ Ви дійсно хочете відмовитись\? Назад Виберіть клас - У вас є нове бойове спорядження за замовчуванням, яке ви можете змінити в розділі Спорядження! + Тепер ви - %s! Ви впевнені, що хочете бути %s\? Не приймати участь @@ -1190,4 +1190,4 @@ Перегляньте рекламу, щоб відкрити знову Шанси випадіння з чарівної скрині Перегляньте рекламу, щоб відродитись - \ No newline at end of file + diff --git a/Habitica/res/values-vi/strings.xml b/Habitica/res/values-vi/strings.xml index d37475728..dc3f9b2c6 100755 --- a/Habitica/res/values-vi/strings.xml +++ b/Habitica/res/values-vi/strings.xml @@ -288,7 +288,7 @@ Bạn có chắc là muốn thay đổi chức nghiệp của mình không\? Điều này sẽ tốn 3 gem đấy. Mở trong cửa hàng Thay đổi chức nghiệp của bạn và hoàn lại điểm chỉ số với 3 gem. - Bạn có Trang bị Chiến đấu mặc định mới mà bạn có thể thay đổi ở dưới phần Trang bị! + Cập nhập đội trên Trạng thái Bạn đã hoàn thành tất cả Việc hằng ngày của mình. Giỏi lắm! Thêm Phần thưởng @@ -1076,4 +1076,4 @@ Chế độ Ban đêm Một người dùng bị chặn không thể gửi bạn Tin nhắn Riêng tư nhưng bạn vẫn sẽ thấy bài đăng của họ ở Quán rượu hay Bang hội. Hoàn thành - \ No newline at end of file + diff --git a/Habitica/res/values-zh-rTW/strings.xml b/Habitica/res/values-zh-rTW/strings.xml index 476742848..48d237cba 100644 --- a/Habitica/res/values-zh-rTW/strings.xml +++ b/Habitica/res/values-zh-rTW/strings.xml @@ -229,7 +229,7 @@ 退出 你確定想要成為%1$s嗎? 你成為了%s! - 你有新的默認的戰鬥裝備,你可以在裝備裡替換! + 選擇職業 返回 你確定要退出嗎? @@ -1229,4 +1229,4 @@ 在訂閱時,你無法刪除你的帳號。請先取消訂閱。 調整你的日子什麼時候切換到默認的午夜。 但是你可以通過你的努力把它們贏回來!加油--你可以的。 - \ No newline at end of file + diff --git a/Habitica/res/values-zh/strings.xml b/Habitica/res/values-zh/strings.xml index 869d4af2f..00663b30c 100644 --- a/Habitica/res/values-zh/strings.xml +++ b/Habitica/res/values-zh/strings.xml @@ -233,7 +233,7 @@ 退出 你确定想要成为%s吗? 你现在是 %s级了! - 你有新的默认战斗装备,你可以在装备栏换上它们! + 选择职业 返回 你确定要退出吗? @@ -1262,4 +1262,4 @@ %d人 - \ No newline at end of file + diff --git a/Habitica/res/values/strings.xml b/Habitica/res/values/strings.xml index fc168b6e8..e48f8a9c1 100644 --- a/Habitica/res/values/strings.xml +++ b/Habitica/res/values/strings.xml @@ -291,9 +291,9 @@ Opt Out Opting Out Are you sure you want to be a %s? - Do you want to change your class to %s for %d gems? + Do you want to change your class to %s for %d Gems? You are now a %s! - You have new default Battle Gear that you can change under Equipment! + You can use %s skills and purchase gear from shops! Choose Class Go Back Are you sure you want to Opt Out? @@ -1381,6 +1381,7 @@ Change class to %s You own all %s gear New gear is released during the seasonal Galas. Until then, theres %d pieces of gear in the Enchanted Armoire to find! + Unlock %s gear and skills You diff --git a/Habitica/src/androidTest/java/com/habitrpg/android/habitica/ui/activities/MainActivityTest.kt b/Habitica/src/androidTest/java/com/habitrpg/android/habitica/ui/activities/MainActivityTest.kt index 75dd45850..900dbafe3 100644 --- a/Habitica/src/androidTest/java/com/habitrpg/android/habitica/ui/activities/MainActivityTest.kt +++ b/Habitica/src/androidTest/java/com/habitrpg/android/habitica/ui/activities/MainActivityTest.kt @@ -4,21 +4,12 @@ import androidx.test.core.app.ActivityScenario import androidx.test.core.app.launchActivity import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.LargeTest -import com.habitrpg.android.habitica.HabiticaBaseApplication import com.habitrpg.android.habitica.R -import com.habitrpg.android.habitica.components.UserComponent -import com.habitrpg.android.habitica.ui.fragments.NavigationDrawerFragment -import com.habitrpg.android.habitica.ui.fragments.tasks.TaskRecyclerViewFragment -import com.habitrpg.android.habitica.ui.fragments.tasks.TasksFragment -import com.habitrpg.android.habitica.ui.viewmodels.MainActivityViewModel -import com.habitrpg.android.habitica.ui.viewmodels.NotificationsViewModel import io.github.kakaocup.kakao.common.views.KView import io.github.kakaocup.kakao.screen.Screen import io.github.kakaocup.kakao.text.KButton import io.github.kakaocup.kakao.toolbar.KToolbar import io.mockk.every -import io.mockk.mockk -import io.mockk.mockkObject import org.junit.After import org.junit.Before import org.junit.Test @@ -43,16 +34,6 @@ class MainActivityTest : ActivityTestCase() { @Before fun setup() { every { hostConfig.hasAuthentication() } returns true - val mockComponent: UserComponent = mockk(relaxed = true) - every { mockComponent.inject(any()) } answers { initializeInjects(this.args.first()) } - every { mockComponent.inject(any()) } answers { initializeInjects(this.args.first()) } - every { mockComponent.inject(any()) } answers { initializeInjects(this.args.first()) } - every { mockComponent.inject(any()) } answers { initializeInjects(this.args.first()) } - every { mockComponent.inject(any()) } answers { initializeInjects(this.args.first()) } - every { mockComponent.inject(any()) } answers { initializeInjects(this.args.first()) } - every { mockComponent.inject(any()) } answers { initializeInjects(this.args.first()) } - mockkObject(HabiticaBaseApplication) - every { HabiticaBaseApplication.userComponent } returns mockComponent } @Test diff --git a/Habitica/src/androidTest/java/com/habitrpg/android/habitica/ui/activities/TaskFormActivityTest.kt b/Habitica/src/androidTest/java/com/habitrpg/android/habitica/ui/activities/TaskFormActivityTest.kt index 82af0c4ca..2cff85672 100644 --- a/Habitica/src/androidTest/java/com/habitrpg/android/habitica/ui/activities/TaskFormActivityTest.kt +++ b/Habitica/src/androidTest/java/com/habitrpg/android/habitica/ui/activities/TaskFormActivityTest.kt @@ -10,7 +10,6 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.LargeTest import com.habitrpg.android.habitica.HabiticaBaseApplication import com.habitrpg.android.habitica.R -import com.habitrpg.android.habitica.components.UserComponent import com.habitrpg.android.habitica.models.tasks.Task import com.habitrpg.shared.habitica.models.tasks.Frequency import com.habitrpg.shared.habitica.models.tasks.TaskType @@ -65,10 +64,7 @@ class TaskFormActivityTest : ActivityTestCase() { @Before fun setup() { every { sharedPreferences.getString("FirstDayOfTheWeek", any()) } returns "-1" - val mockComponent: UserComponent = mockk(relaxed = true) - every { mockComponent.inject(any()) } answers { initializeInjects(this.args.first()) } mockkObject(HabiticaBaseApplication) - every { HabiticaBaseApplication.userComponent } returns mockComponent } private fun hasBasicTaskEditingViews() { diff --git a/Habitica/src/androidTest/java/com/habitrpg/android/habitica/ui/fragments/inventory/items/ItemRecyclerFragmentTest.kt b/Habitica/src/androidTest/java/com/habitrpg/android/habitica/ui/fragments/inventory/items/ItemRecyclerFragmentTest.kt index 96be8d381..4fb4aee8a 100644 --- a/Habitica/src/androidTest/java/com/habitrpg/android/habitica/ui/fragments/inventory/items/ItemRecyclerFragmentTest.kt +++ b/Habitica/src/androidTest/java/com/habitrpg/android/habitica/ui/fragments/inventory/items/ItemRecyclerFragmentTest.kt @@ -8,7 +8,6 @@ import androidx.test.espresso.UiController import androidx.test.espresso.ViewAction import com.habitrpg.android.habitica.HabiticaBaseApplication import com.habitrpg.android.habitica.R -import com.habitrpg.android.habitica.components.UserComponent import com.habitrpg.android.habitica.databinding.FragmentRecyclerviewBinding import com.habitrpg.android.habitica.interactors.HatchPetUseCase import com.habitrpg.android.habitica.models.inventory.Food @@ -78,11 +77,6 @@ internal class ItemRecyclerFragmentTest : FragmentTestCase()) } answers { initializeInjects(this.args.first()) } - mockkObject(HabiticaBaseApplication) - every { HabiticaBaseApplication.userComponent } returns mockComponent } override fun launchFragment(args: Bundle?) { diff --git a/Habitica/src/androidTest/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/PetDetailFragmentTest.kt b/Habitica/src/androidTest/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/PetDetailFragmentTest.kt index 95f8768b7..818af455b 100644 --- a/Habitica/src/androidTest/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/PetDetailFragmentTest.kt +++ b/Habitica/src/androidTest/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/PetDetailFragmentTest.kt @@ -4,7 +4,6 @@ import android.os.Bundle import androidx.fragment.app.testing.launchFragmentInContainer import com.habitrpg.android.habitica.HabiticaBaseApplication import com.habitrpg.android.habitica.R -import com.habitrpg.android.habitica.components.UserComponent import com.habitrpg.android.habitica.databinding.FragmentRecyclerviewBinding import com.habitrpg.android.habitica.interactors.FeedPetUseCase import com.habitrpg.android.habitica.models.user.OwnedItem @@ -52,11 +51,6 @@ internal class PetDetailRecyclerFragmentTest : fragment = spyk() fragment.shouldInitializeComponent = false - - val mockComponent: UserComponent = mockk(relaxed = true) - every { mockComponent.inject(any()) } answers { initializeInjects(this.args.first()) } - mockkObject(HabiticaBaseApplication) - every { HabiticaBaseApplication.userComponent } returns mockComponent } override fun launchFragment(args: Bundle?) { diff --git a/Habitica/src/debug/java/com/habitrpg/android/habitica/HabiticaApplication.java b/Habitica/src/debug/java/com/habitrpg/android/habitica/HabiticaApplication.java index afc43c2c9..cfb2767b5 100644 --- a/Habitica/src/debug/java/com/habitrpg/android/habitica/HabiticaApplication.java +++ b/Habitica/src/debug/java/com/habitrpg/android/habitica/HabiticaApplication.java @@ -1,8 +1,4 @@ package com.habitrpg.android.habitica; -import com.habitrpg.android.habitica.components.AppComponent; -import com.habitrpg.android.habitica.components.DaggerAppComponent; -import com.habitrpg.android.habitica.modules.AppModule; - public class HabiticaApplication extends HabiticaBaseApplication { } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/HabiticaBaseApplication.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/HabiticaBaseApplication.kt index b60edd96f..60af70990 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/HabiticaBaseApplication.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/HabiticaBaseApplication.kt @@ -27,6 +27,7 @@ import com.habitrpg.android.habitica.data.ApiClient import com.habitrpg.android.habitica.helpers.AdHandler import com.habitrpg.android.habitica.helpers.AmplitudeManager import com.habitrpg.android.habitica.helpers.notifications.PushNotificationManager +import com.habitrpg.android.habitica.modules.AuthenticationHandler import com.habitrpg.android.habitica.ui.activities.BaseActivity import com.habitrpg.android.habitica.ui.activities.LoginActivity import com.habitrpg.android.habitica.ui.views.HabiticaIconsHelper @@ -53,6 +54,8 @@ abstract class HabiticaBaseApplication : Application(), Application.ActivityLife internal lateinit var analyticsManager: AnalyticsManager @Inject internal lateinit var pushNotificationManager: PushNotificationManager + @Inject + internal lateinit var authenticationHandler: AuthenticationHandler /** * For better performance billing class should be used as singleton */ diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/components/AppComponent.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/components/AppComponent.kt deleted file mode 100644 index b2e6ba145..000000000 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/components/AppComponent.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.habitrpg.android.habitica.components - -import com.habitrpg.android.habitica.modules.ApiModule -import com.habitrpg.android.habitica.modules.AppModule -import com.habitrpg.android.habitica.modules.DeveloperModule -import com.habitrpg.android.habitica.modules.RepositoryModule -import com.habitrpg.android.habitica.modules.UserModule -import com.habitrpg.android.habitica.modules.UserRepositoryModule -import dagger.Component -import javax.inject.Singleton - -@Singleton -@Component(modules = [DeveloperModule::class, AppModule::class, ApiModule::class, RepositoryModule::class]) -interface AppComponent { - fun plus( - userModule : UserModule?, - userRepositoryModule : UserRepositoryModule? - ) : UserComponent? -} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/components/UserComponent.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/components/UserComponent.kt deleted file mode 100644 index 78b152db1..000000000 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/components/UserComponent.kt +++ /dev/null @@ -1,13 +0,0 @@ -package com.habitrpg.android.habitica.components - -import com.habitrpg.android.habitica.modules.UserModule -import com.habitrpg.android.habitica.modules.UserRepositoryModule -import dagger.Subcomponent -import dagger.hilt.android.scopes.ActivityRetainedScoped -import dagger.hilt.android.scopes.ServiceScoped - -@ActivityRetainedScoped -@ServiceScoped -@Subcomponent(modules = [UserModule::class, UserRepositoryModule::class]) -interface UserComponent { -} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/TaskRepository.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/TaskRepository.kt index b768f2623..198e969b8 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/TaskRepository.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/TaskRepository.kt @@ -57,8 +57,7 @@ interface TaskRepository : BaseRepository { fun createTaskInBackground(task: Task, assignChanges: Map>) - fun getTaskCopies(userId: String): Flow> - + fun getTaskCopies(): Flow> fun getTaskCopies(tasks: List): List suspend fun retrieveDailiesFromDate(date: Date): TaskList? diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/BaseRepositoryImpl.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/BaseRepositoryImpl.kt index f7754e49c..83f8b6744 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/BaseRepositoryImpl.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/BaseRepositoryImpl.kt @@ -4,13 +4,17 @@ import com.habitrpg.android.habitica.data.ApiClient import com.habitrpg.android.habitica.data.BaseRepository import com.habitrpg.android.habitica.data.local.BaseLocalRepository import com.habitrpg.android.habitica.models.BaseObject +import com.habitrpg.android.habitica.modules.AuthenticationHandler abstract class BaseRepositoryImpl( protected val localRepository: T, protected val apiClient: ApiClient, - protected val userID: String = "" + protected val authenticationHandler : AuthenticationHandler ) : BaseRepository { + val currentUserID : String + get() = authenticationHandler.currentUserID ?: "" + override fun close() { this.localRepository.close() } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/ChallengeRepositoryImpl.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/ChallengeRepositoryImpl.kt index dec714963..0a900c4fb 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/ChallengeRepositoryImpl.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/ChallengeRepositoryImpl.kt @@ -8,6 +8,7 @@ import com.habitrpg.android.habitica.models.social.Challenge import com.habitrpg.android.habitica.models.social.ChallengeMembership import com.habitrpg.android.habitica.models.tasks.Task import com.habitrpg.android.habitica.models.tasks.TaskList +import com.habitrpg.android.habitica.modules.AuthenticationHandler import com.habitrpg.shared.habitica.models.tasks.TaskType import com.habitrpg.shared.habitica.models.tasks.TasksOrder import kotlinx.coroutines.flow.Flow @@ -15,19 +16,19 @@ import kotlinx.coroutines.flow.Flow class ChallengeRepositoryImpl( localRepository: ChallengeLocalRepository, apiClient: ApiClient, - userID: String -) : BaseRepositoryImpl(localRepository, apiClient, userID), ChallengeRepository { + authenticationHandler: AuthenticationHandler +) : BaseRepositoryImpl(localRepository, apiClient, authenticationHandler), ChallengeRepository { override fun isChallengeMember(challengeID: String): Flow { - return localRepository.isChallengeMember(userID, challengeID) + return localRepository.isChallengeMember(currentUserID, challengeID) } override fun getChallengepMembership(id: String): Flow { - return localRepository.getChallengeMembership(userID, id) + return localRepository.getChallengeMembership(currentUserID, id) } override fun getChallengeMemberships(): Flow> { - return localRepository.getChallengeMemberships(userID) + return localRepository.getChallengeMemberships(currentUserID) } override fun getChallenge(challengeId: String): Flow { @@ -130,26 +131,26 @@ class ChallengeRepositoryImpl( } override fun getUserChallenges(userId: String?): Flow> { - return localRepository.getUserChallenges(userId ?: userID) + return localRepository.getUserChallenges(userId ?: currentUserID) } override suspend fun retrieveChallenges(page: Int, memberOnly: Boolean): List? { val challenges = apiClient.getUserChallenges(page, memberOnly) if (challenges != null) { - localRepository.saveChallenges(challenges, page == 0, memberOnly, userID) + localRepository.saveChallenges(challenges, page == 0, memberOnly, currentUserID) } return challenges } override suspend fun leaveChallenge(challenge: Challenge, keepTasks: String): Void? { apiClient.leaveChallenge(challenge.id ?: "", LeaveChallengeBody(keepTasks)) - localRepository.setParticipating(userID, challenge.id ?: "", false) + localRepository.setParticipating(currentUserID, challenge.id ?: "", false) return null } override suspend fun joinChallenge(challenge: Challenge): Challenge? { val returnedChallenge = apiClient.joinChallenge(challenge.id ?: "") ?: return null - localRepository.setParticipating(userID, returnedChallenge.id ?: "", true) + localRepository.setParticipating(currentUserID, returnedChallenge.id ?: "", true) return returnedChallenge } } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/ContentRepositoryImpl.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/ContentRepositoryImpl.kt index 0800867f1..ea13d93ba 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/ContentRepositoryImpl.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/ContentRepositoryImpl.kt @@ -8,6 +8,7 @@ import com.habitrpg.android.habitica.helpers.AprilFoolsHandler import com.habitrpg.android.habitica.models.ContentResult import com.habitrpg.android.habitica.models.WorldState import com.habitrpg.android.habitica.models.inventory.SpecialItem +import com.habitrpg.android.habitica.modules.AuthenticationHandler import io.realm.RealmList import kotlinx.coroutines.flow.Flow import java.util.Date @@ -15,8 +16,9 @@ import java.util.Date class ContentRepositoryImpl( localRepository: T, apiClient: ApiClient, - context: Context -) : BaseRepositoryImpl(localRepository, apiClient), ContentRepository { + context: Context, + authenticationHandler: AuthenticationHandler +) : BaseRepositoryImpl(localRepository, apiClient, authenticationHandler), ContentRepository { private val mysteryItem = SpecialItem.makeMysteryItem(context) diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/CustomizationRepositoryImpl.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/CustomizationRepositoryImpl.kt index ee17bff76..fee731782 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/CustomizationRepositoryImpl.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/CustomizationRepositoryImpl.kt @@ -4,13 +4,14 @@ import com.habitrpg.android.habitica.data.ApiClient import com.habitrpg.android.habitica.data.CustomizationRepository import com.habitrpg.android.habitica.data.local.CustomizationLocalRepository import com.habitrpg.android.habitica.models.inventory.Customization +import com.habitrpg.android.habitica.modules.AuthenticationHandler import kotlinx.coroutines.flow.Flow class CustomizationRepositoryImpl( localRepository: CustomizationLocalRepository, apiClient: ApiClient, - userID: String -) : BaseRepositoryImpl(localRepository, apiClient, userID), CustomizationRepository { + authenticationHandler: AuthenticationHandler +) : BaseRepositoryImpl(localRepository, apiClient, authenticationHandler), CustomizationRepository { override fun getCustomizations(type: String, category: String?, onlyAvailable: Boolean): Flow> { return localRepository.getCustomizations(type, category, onlyAvailable) diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/FAQRepositoryImpl.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/FAQRepositoryImpl.kt index 8c74b2722..d6c229a86 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/FAQRepositoryImpl.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/FAQRepositoryImpl.kt @@ -4,14 +4,20 @@ import com.habitrpg.android.habitica.data.ApiClient import com.habitrpg.android.habitica.data.FAQRepository import com.habitrpg.android.habitica.data.local.FAQLocalRepository import com.habitrpg.android.habitica.models.FAQArticle +import com.habitrpg.android.habitica.modules.AuthenticationHandler import kotlinx.coroutines.flow.Flow -class FAQRepositoryImpl(localRepository: FAQLocalRepository, apiClient: ApiClient, userID: String) : BaseRepositoryImpl(localRepository, apiClient, userID), FAQRepository { - override fun getArticle(position: Int): Flow { +class FAQRepositoryImpl( + localRepository : FAQLocalRepository, + apiClient : ApiClient, + authenticationHandler : AuthenticationHandler +) : BaseRepositoryImpl(localRepository, apiClient, authenticationHandler), + FAQRepository { + override fun getArticle(position : Int) : Flow { return localRepository.getArticle(position) } - override fun getArticles(): Flow> { + override fun getArticles() : Flow> { return localRepository.articles } } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/InventoryRepositoryImpl.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/InventoryRepositoryImpl.kt index ae27eefa1..cf537109d 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/InventoryRepositoryImpl.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/InventoryRepositoryImpl.kt @@ -1,3 +1,5 @@ +@file:OptIn(ExperimentalCoroutinesApi::class) + package com.habitrpg.android.habitica.data.implementation import com.habitrpg.android.habitica.data.ApiClient @@ -21,16 +23,19 @@ import com.habitrpg.android.habitica.models.user.OwnedItem import com.habitrpg.android.habitica.models.user.OwnedMount import com.habitrpg.android.habitica.models.user.OwnedPet import com.habitrpg.android.habitica.models.user.User +import com.habitrpg.android.habitica.modules.AuthenticationHandler import com.habitrpg.shared.habitica.models.responses.FeedResponse +import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.firstOrNull +import kotlinx.coroutines.flow.flatMapLatest class InventoryRepositoryImpl( localRepository: InventoryLocalRepository, apiClient: ApiClient, - userID: String, + authenticationHandler: AuthenticationHandler, var appConfigManager: AppConfigManager -) : BaseRepositoryImpl(localRepository, apiClient, userID), InventoryRepository { +) : BaseRepositoryImpl(localRepository, apiClient, authenticationHandler), InventoryRepository { override fun getQuestContent(keys: List) = localRepository.getQuestContent(keys) override fun getQuestContent(key: String) = localRepository.getQuestContent(key) @@ -72,11 +77,11 @@ class InventoryRepositoryImpl( } override fun getOwnedItems(itemType: String, includeZero: Boolean): Flow> { - return localRepository.getOwnedItems(itemType, userID, includeZero) + return authenticationHandler.userIDFlow.flatMapLatest { localRepository.getOwnedItems(itemType, it, includeZero) } } override fun getOwnedItems(includeZero: Boolean): Flow> { - return localRepository.getOwnedItems(userID, includeZero) + return authenticationHandler.userIDFlow.flatMapLatest { localRepository.getOwnedItems(it, includeZero) } } override fun getItems(itemClass: Class, keys: Array): Flow> { @@ -115,7 +120,7 @@ class InventoryRepositoryImpl( } override fun getOwnedMounts(): Flow> { - return localRepository.getOwnedMounts(userID) + return authenticationHandler.userIDFlow.flatMapLatest { localRepository.getOwnedMounts(it) } } override fun getPets(): Flow> { @@ -127,7 +132,7 @@ class InventoryRepositoryImpl( } override fun getOwnedPets(): Flow> { - return localRepository.getOwnedPets(userID) + return authenticationHandler.userIDFlow.flatMapLatest { localRepository.getOwnedPets(it) } } override fun updateOwnedEquipment(user: User) { @@ -135,11 +140,11 @@ class InventoryRepositoryImpl( } override suspend fun changeOwnedCount(type: String, key: String, amountToAdd: Int) { - localRepository.changeOwnedCount(type, key, userID, amountToAdd) + localRepository.changeOwnedCount(type, key, currentUserID, amountToAdd) } override suspend fun sellItem(type: String, key: String): User? { - val item = localRepository.getOwnedItem(userID, type, key, true).firstOrNull() ?: return null + val item = localRepository.getOwnedItem(currentUserID, type, key, true).firstOrNull() ?: return null return sellItem(item) } @@ -162,7 +167,7 @@ class InventoryRepositoryImpl( liveItem?.numberOwned = (liveItem?.numberOwned ?: 0) - 1 } val user = apiClient.sellItem(item.type, item.key) ?: return null - return localRepository.soldItem(userID, user) + return localRepository.soldItem(currentUserID, user) } override suspend fun equipGear(equipment: String, asCostume: Boolean): Items? { @@ -170,7 +175,7 @@ class InventoryRepositoryImpl( } override suspend fun equip(type: String, key: String): Items? { - val liveUser = localRepository.getLiveUser(userID) + val liveUser = localRepository.getLiveUser(currentUserID) if (liveUser != null) { localRepository.modify(liveUser) { user -> @@ -214,17 +219,17 @@ class InventoryRepositoryImpl( override suspend fun feedPet(pet: Pet, food: Food): FeedResponse? { val feedResponse = apiClient.feedPet(pet.key ?: "", food.key) ?: return null - localRepository.feedPet(food.key, pet.key ?: "", feedResponse.value ?: 0, userID) + localRepository.feedPet(food.key, pet.key ?: "", feedResponse.value ?: 0, currentUserID) return feedResponse } override suspend fun hatchPet(egg: Egg, hatchingPotion: HatchingPotion, successFunction: () -> Unit): Items? { if (appConfigManager.enableLocalChanges()) { - localRepository.hatchPet(egg.key, hatchingPotion.key, userID) + localRepository.hatchPet(egg.key, hatchingPotion.key, currentUserID) successFunction() } val items = apiClient.hatchPet(egg.key, hatchingPotion.key) ?: return null - localRepository.save(items, userID) + localRepository.save(items, currentUserID) if (!appConfigManager.enableLocalChanges()) { successFunction() } @@ -233,13 +238,13 @@ class InventoryRepositoryImpl( override suspend fun inviteToQuest(quest: QuestContent): Quest? { val newQuest = apiClient.inviteToQuest("party", quest.key) - localRepository.changeOwnedCount("quests", quest.key, userID, -1) + localRepository.changeOwnedCount("quests", quest.key, currentUserID, -1) return newQuest } override suspend fun buyItem(user: User?, id: String, value: Double, purchaseQuantity: Int): BuyResponse? { val buyResponse = apiClient.buyItem(id, purchaseQuantity) ?: return null - val foundUser = user ?: localRepository.getLiveUser(userID) ?: return buyResponse + val foundUser = user ?: localRepository.getLiveUser(currentUserID) ?: return buyResponse val copiedUser = localRepository.getUnmanagedCopy(foundUser) if (buyResponse.items != null) { copiedUser.items = buyResponse.items diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/SocialRepositoryImpl.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/SocialRepositoryImpl.kt index 4de455798..2babb5f00 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/SocialRepositoryImpl.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/SocialRepositoryImpl.kt @@ -1,3 +1,5 @@ +@file:OptIn(ExperimentalCoroutinesApi::class) + package com.habitrpg.android.habitica.data.implementation import com.habitrpg.android.habitica.BuildConfig @@ -14,17 +16,20 @@ import com.habitrpg.android.habitica.models.social.Group import com.habitrpg.android.habitica.models.social.GroupMembership import com.habitrpg.android.habitica.models.social.InboxConversation import com.habitrpg.android.habitica.models.user.User +import com.habitrpg.android.habitica.modules.AuthenticationHandler +import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.emptyFlow import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.firstOrNull +import kotlinx.coroutines.flow.flatMapLatest import java.util.UUID class SocialRepositoryImpl( localRepository: SocialLocalRepository, apiClient: ApiClient, - userID: String -) : BaseRepositoryImpl(localRepository, apiClient, userID), SocialRepository { + authenticationHandler: AuthenticationHandler +) : BaseRepositoryImpl(localRepository, apiClient, authenticationHandler), SocialRepository { override suspend fun transferGroupOwnership(groupID: String, userID: String): Group? { val group = localRepository.getGroup(groupID).first()?.let { localRepository.getUnmanagedCopy(it) } group?.leaderID = userID @@ -52,10 +57,10 @@ class SocialRepositoryImpl( return apiClient.retrievePartySeekingUsers(page) } - override fun getGroupMembership(id: String) = localRepository.getGroupMembership(userID, id) + override fun getGroupMembership(id: String) = authenticationHandler.userIDFlow.flatMapLatest { localRepository.getGroupMembership(it, id) } override fun getGroupMemberships(): Flow> { - return localRepository.getGroupMemberships(userID) + return authenticationHandler.userIDFlow.flatMapLatest { localRepository.getGroupMemberships(it) } } override suspend fun retrieveGroupChat(groupId: String): List? { @@ -75,7 +80,7 @@ class SocialRepositoryImpl( override suspend fun flagMessage(chatMessageID: String, additionalInfo: String, groupID: String?): Void? { return when { chatMessageID.isBlank() -> return null - userID == BuildConfig.ANDROID_TESTING_UUID -> return null + currentUserID == BuildConfig.ANDROID_TESTING_UUID -> return null else -> { val data = mutableMapOf() data["comment"] = additionalInfo @@ -92,8 +97,8 @@ class SocialRepositoryImpl( if (chatMessage.id.isBlank()) { return null } - val liked = chatMessage.userLikesMessage(userID) - localRepository.likeMessage(chatMessage, userID, !liked) + val liked = chatMessage.userLikesMessage(currentUserID) + localRepository.likeMessage(chatMessage, currentUserID, !liked) val message = apiClient.likeMessage(chatMessage.groupId ?: "", chatMessage.id) message?.groupId = chatMessage.groupId message?.let { localRepository.save(it) } @@ -142,7 +147,7 @@ class SocialRepositoryImpl( } apiClient.leaveGroup(id, if (keepChallenges) "remain-in-challenges" else "leave-challenges") - localRepository.updateMembership(userID, id, false) + localRepository.updateMembership(currentUserID, id, false) return localRepository.getGroup(id).firstOrNull() } @@ -152,7 +157,7 @@ class SocialRepositoryImpl( } val group = apiClient.joinGroup(id) group?.let { - localRepository.updateMembership(userID, id, true) + localRepository.updateMembership(currentUserID, id, true) localRepository.save(group) } return group @@ -200,9 +205,9 @@ class SocialRepositoryImpl( val groups = apiClient.listGroups(type) ?: return null if ("guilds" == type) { val memberships = groups.map { - GroupMembership(userID, it.id) + GroupMembership(currentUserID, it.id) } - localRepository.saveGroupMemberships(userID, memberships) + localRepository.saveGroupMemberships(currentUserID, memberships) } localRepository.save(groups) return groups @@ -212,22 +217,22 @@ class SocialRepositoryImpl( override fun getPublicGuilds() = localRepository.getPublicGuilds() - override fun getInboxConversations() = localRepository.getInboxConversation(userID) + override fun getInboxConversations() = authenticationHandler.userIDFlow.flatMapLatest { localRepository.getInboxConversation(it) } - override fun getInboxMessages(replyToUserID: String?) = localRepository.getInboxMessages(userID, replyToUserID) + override fun getInboxMessages(replyToUserID: String?) = authenticationHandler.userIDFlow.flatMapLatest { localRepository.getInboxMessages(it, replyToUserID) } override suspend fun retrieveInboxMessages(uuid: String, page: Int): List? { val messages = apiClient.retrieveInboxMessages(uuid, page) ?: return null messages.forEach { it.isInboxMessage = true } - localRepository.saveInboxMessages(userID, uuid, messages, page) + localRepository.saveInboxMessages(currentUserID, uuid, messages, page) return messages } override suspend fun retrieveInboxConversations(): List? { val conversations = apiClient.retrieveInboxConversations() ?: return null - localRepository.saveInboxConversations(userID, conversations) + localRepository.saveInboxConversations(currentUserID, conversations) return conversations } @@ -306,7 +311,7 @@ class SocialRepositoryImpl( } } - override fun getUserGroups(type: String?) = localRepository.getUserGroups(userID, type) + override fun getUserGroups(type: String?) = authenticationHandler.userIDFlow.flatMapLatest { localRepository.getUserGroups(it, type) } override suspend fun acceptQuest(user: User?, partyId: String): Void? { apiClient.acceptQuest(partyId) @@ -342,7 +347,7 @@ class SocialRepositoryImpl( override suspend fun rejectGroupInvite(groupId: String): Void? { apiClient.rejectGroupInvite(groupId) - localRepository.rejectGroupInvitation(userID, groupId) + localRepository.rejectGroupInvitation(currentUserID, groupId) return null } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/TagRepositoryImpl.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/TagRepositoryImpl.kt index ff56233b0..cf8d67770 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/TagRepositoryImpl.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/TagRepositoryImpl.kt @@ -1,54 +1,62 @@ +@file:OptIn(ExperimentalCoroutinesApi::class) + package com.habitrpg.android.habitica.data.implementation import com.habitrpg.android.habitica.data.ApiClient import com.habitrpg.android.habitica.data.TagRepository import com.habitrpg.android.habitica.data.local.TagLocalRepository import com.habitrpg.android.habitica.models.Tag +import com.habitrpg.android.habitica.modules.AuthenticationHandler +import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.flatMapLatest -class TagRepositoryImpl(localRepository: TagLocalRepository, apiClient: ApiClient, userID: String) : BaseRepositoryImpl(localRepository, apiClient, userID), TagRepository { +class TagRepositoryImpl( + localRepository : TagLocalRepository, + apiClient : ApiClient, + authenticationHandler : AuthenticationHandler +) : BaseRepositoryImpl(localRepository, apiClient, authenticationHandler), + TagRepository { - override fun getTags(): Flow> { - return getTags(userID) - } + override fun getTags() = authenticationHandler.userIDFlow.flatMapLatest { getTags(it) } - override fun getTags(userId: String): Flow> { + override fun getTags(userId : String) : Flow> { return localRepository.getTags(userId) } - override suspend fun createTag(tag: Tag): Tag? { + override suspend fun createTag(tag : Tag) : Tag? { val savedTag = apiClient.createTag(tag) ?: return null - savedTag.userId = userID + savedTag.userId = currentUserID localRepository.save(savedTag) return savedTag } - override suspend fun updateTag(tag: Tag): Tag? { + override suspend fun updateTag(tag : Tag) : Tag? { val savedTag = apiClient.updateTag(tag.id, tag) ?: return null - savedTag.userId = userID + savedTag.userId = currentUserID localRepository.save(savedTag) return savedTag } - override suspend fun deleteTag(id: String): Void? { + override suspend fun deleteTag(id : String) : Void? { apiClient.deleteTag(id) localRepository.deleteTag(id) return null } - override suspend fun createTags(tags: Collection): List { + override suspend fun createTags(tags : Collection) : List { return tags.mapNotNull { createTag(it) } } - override suspend fun updateTags(tags: Collection): List { + override suspend fun updateTags(tags : Collection) : List { return tags.mapNotNull { updateTag(it) } } - override suspend fun deleteTags(tagIds: Collection): List { + override suspend fun deleteTags(tagIds : Collection) : List { return tagIds.mapNotNull { deleteTag(it) } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/TaskRepositoryImpl.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/TaskRepositoryImpl.kt index d33bb5577..3aa0946fb 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/TaskRepositoryImpl.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/TaskRepositoryImpl.kt @@ -13,6 +13,7 @@ import com.habitrpg.android.habitica.models.tasks.Task import com.habitrpg.android.habitica.models.tasks.TaskList import com.habitrpg.android.habitica.models.user.OwnedItem import com.habitrpg.android.habitica.models.user.User +import com.habitrpg.android.habitica.modules.AuthenticationHandler import com.habitrpg.common.habitica.helpers.AnalyticsManager import com.habitrpg.common.habitica.helpers.launchCatching import com.habitrpg.shared.habitica.models.responses.TaskDirection @@ -20,26 +21,29 @@ import com.habitrpg.shared.habitica.models.responses.TaskDirectionData import com.habitrpg.shared.habitica.models.responses.TaskScoringResult import com.habitrpg.shared.habitica.models.tasks.TaskType import com.habitrpg.shared.habitica.models.tasks.TasksOrder +import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.MainScope import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.firstOrNull +import kotlinx.coroutines.flow.flatMapLatest import kotlinx.coroutines.flow.map import java.text.SimpleDateFormat import java.util.Date import java.util.Locale import java.util.UUID +@ExperimentalCoroutinesApi class TaskRepositoryImpl( localRepository: TaskLocalRepository, apiClient: ApiClient, - userID: String, + authenticationHandler : AuthenticationHandler, val appConfigManager: AppConfigManager, val analyticsManager: AnalyticsManager -) : BaseRepositoryImpl(localRepository, apiClient, userID), TaskRepository { +) : BaseRepositoryImpl(localRepository, apiClient, authenticationHandler), TaskRepository { private var lastTaskAction: Long = 0 override fun getTasks(taskType: TaskType, userID: String?, includedGroupIDs: Array): Flow> = - this.localRepository.getTasks(taskType, userID ?: this.userID, includedGroupIDs) + this.localRepository.getTasks(taskType, userID ?: authenticationHandler.currentUserID ?: "", includedGroupIDs) override fun saveTasks(userId: String, order: TasksOrder, tasks: TaskList) { localRepository.saveTasks(userId, order, tasks) @@ -54,7 +58,7 @@ class TaskRepositoryImpl( override suspend fun retrieveCompletedTodos(userId: String?): TaskList? { val taskList = this.apiClient.getTasks("completedTodos") ?: return null val tasks = taskList.tasks - this.localRepository.saveCompletedTodos(userId ?: this.userID, tasks.values) + this.localRepository.saveCompletedTodos(userId ?: authenticationHandler.currentUserID ?: "", tasks.values) return taskList } @@ -92,7 +96,7 @@ class TaskRepositoryImpl( lastTaskAction = now val res = this.apiClient.postTaskDirection(id, (if (up) TaskDirection.UP else TaskDirection.DOWN).text) ?: return null // There are cases where the user object is not set correctly. So the app refetches it as a fallback - val thisUser = user ?: localRepository.getUser(userID).firstOrNull() ?: return null + val thisUser = user ?: localRepository.getUser(authenticationHandler.currentUserID ?: "").firstOrNull() ?: return null // save local task changes analyticsManager.logEvent( @@ -132,7 +136,7 @@ class TaskRepositoryImpl( if (bgTask.type != TaskType.REWARD && (bgTask.value - localDelta) + res.delta != bgTask.value) { bgTask.value = (bgTask.value - localDelta) + res.delta if (TaskType.DAILY == bgTask.type || TaskType.TODO == bgTask.type) { - bgTask.completeForUser(userID, up) + bgTask.completeForUser(authenticationHandler.currentUserID ?: "", up) if (TaskType.DAILY == bgTask.type) { if (up) { bgTask.streak = (bgTask.streak ?: 0) + 1 @@ -243,7 +247,7 @@ class TaskRepositoryImpl( task.ownerID = if (task.isGroupTask) { task.group?.groupID ?: "" } else { - userID + authenticationHandler.currentUserID ?: "" } if (task.id == null) { task.id = UUID.randomUUID().toString() @@ -362,8 +366,9 @@ class TaskRepositoryImpl( } } - override fun getTaskCopies(userId: String): Flow> = - localRepository.getTasks(userId).map { localRepository.getUnmanagedCopy(it) } + override fun getTaskCopies(): Flow> = authenticationHandler.userIDFlow.flatMapLatest { + localRepository.getTasks(it) + }.map { localRepository.getUnmanagedCopy(it) } override fun getTaskCopies(tasks: List): List = localRepository.getUnmanagedCopy(tasks) @@ -373,7 +378,7 @@ class TaskRepositoryImpl( } override suspend fun syncErroredTasks(): List? { - val tasks = localRepository.getErroredTasks(userID).firstOrNull() + val tasks = localRepository.getErroredTasks(currentUserID ?: "").firstOrNull() return tasks?.map { localRepository.getUnmanagedCopy(it) }?.mapNotNull { if (it.isCreating) { createTask(it, true) @@ -388,6 +393,6 @@ class TaskRepositoryImpl( } override fun getTasksForChallenge(challengeID: String?): Flow> { - return localRepository.getTasksForChallenge(challengeID, userID) + return localRepository.getTasksForChallenge(challengeID, currentUserID ?: "") } } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/TutorialRepositoryImpl.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/TutorialRepositoryImpl.kt index b6bd7e63f..9edda31b7 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/TutorialRepositoryImpl.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/TutorialRepositoryImpl.kt @@ -4,13 +4,14 @@ import com.habitrpg.android.habitica.data.ApiClient import com.habitrpg.android.habitica.data.TutorialRepository import com.habitrpg.android.habitica.data.local.TutorialLocalRepository import com.habitrpg.android.habitica.models.TutorialStep +import com.habitrpg.android.habitica.modules.AuthenticationHandler import kotlinx.coroutines.flow.Flow class TutorialRepositoryImpl( localRepository: TutorialLocalRepository, apiClient: ApiClient, - userID: String -) : BaseRepositoryImpl(localRepository, apiClient, userID), TutorialRepository { + authenticationHandler: AuthenticationHandler +) : BaseRepositoryImpl(localRepository, apiClient, authenticationHandler), TutorialRepository { override fun getTutorialStep(key: String): Flow = localRepository.getTutorialStep(key) diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/UserRepositoryImpl.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/UserRepositoryImpl.kt index 1154a3cff..8c6f4922b 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/UserRepositoryImpl.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/UserRepositoryImpl.kt @@ -17,33 +17,37 @@ import com.habitrpg.android.habitica.models.tasks.Task import com.habitrpg.android.habitica.models.user.Stats import com.habitrpg.android.habitica.models.user.User import com.habitrpg.android.habitica.models.user.UserQuestStatus +import com.habitrpg.android.habitica.modules.AuthenticationHandler import com.habitrpg.common.habitica.helpers.AnalyticsManager import com.habitrpg.shared.habitica.models.responses.TaskDirection import com.habitrpg.shared.habitica.models.tasks.Attribute import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.firstOrNull +import kotlinx.coroutines.flow.flatMapLatest import kotlinx.coroutines.flow.map import kotlinx.coroutines.withContext import java.util.Date import java.util.GregorianCalendar import java.util.concurrent.TimeUnit +@OptIn(ExperimentalCoroutinesApi::class) class UserRepositoryImpl( localRepository: UserLocalRepository, apiClient: ApiClient, - userID: String, + authenticationHandler: AuthenticationHandler, private val taskRepository: TaskRepository, private val appConfigManager: AppConfigManager, private val analyticsManager: AnalyticsManager -) : BaseRepositoryImpl(localRepository, apiClient, userID), UserRepository { +) : BaseRepositoryImpl(localRepository, apiClient, authenticationHandler), UserRepository { companion object { private var lastReadNotification: String? = null private var lastSync: Date? = null } - override fun getUser(): Flow = getUser(userID) + override fun getUser(): Flow = authenticationHandler.userIDFlow.flatMapLatest { getUser(it) } override fun getUser(userID: String): Flow = localRepository.getUser(userID) private suspend fun updateUser(userID: String, updateData: Map): User? { @@ -57,11 +61,11 @@ class UserRepositoryImpl( } override suspend fun updateUser(updateData: Map): User? { - return updateUser(userID, updateData) + return updateUser(currentUserID, updateData) } override suspend fun updateUser(key : String, value : Any?): User? { - return updateUser(userID, key, value) + return updateUser(currentUserID, key, value) } @Suppress("ReturnCount") @@ -156,7 +160,7 @@ class UserRepositoryImpl( override suspend fun unlockPath(path: String, price: Int): UnlockResponse? { val unlockResponse = apiClient.unlockPath(path) ?: return null - val user = localRepository.getUser(userID).firstOrNull() ?: return unlockResponse + val user = localRepository.getUser(currentUserID).firstOrNull() ?: return unlockResponse localRepository.modify(user) { liveUser -> unlockResponse.preferences?.let { liveUser.preferences = it } liveUser.purchased = unlockResponse.purchased @@ -176,7 +180,7 @@ class UserRepositoryImpl( return apiClient.readNotification(id) } override fun getUserQuestStatus(): Flow { - return localRepository.getUserQuestStatus(userID) + return localRepository.getUserQuestStatus(currentUserID) } override suspend fun reroll(): User? { @@ -214,7 +218,7 @@ class UserRepositoryImpl( } else { apiClient.updateUsername(newLoginName.trim()) } - val user = localRepository.getUser(userID).firstOrNull() ?: return null + val user = localRepository.getUser(currentUserID).firstOrNull() ?: return null localRepository.modify(user) { liveUser -> liveUser.authentication?.localAuthentication?.username = newLoginName liveUser.flags?.verifiedUsername = true @@ -344,7 +348,7 @@ class UserRepositoryImpl( } override suspend fun retrieveAchievements(): List? { - val achievements = apiClient.getMemberAchievements(userID) ?: return null + val achievements = apiClient.getMemberAchievements(currentUserID) ?: return null localRepository.save(achievements) return achievements } @@ -354,18 +358,18 @@ class UserRepositoryImpl( } override fun getQuestAchievements(): Flow> { - return localRepository.getQuestAchievements(userID) + return localRepository.getQuestAchievements(currentUserID) } override suspend fun retrieveTeamPlans(): List? { val teams = apiClient.getTeamPlans() ?: return null - teams.forEach { it.userID = userID } + teams.forEach { it.userID = currentUserID } localRepository.save(teams) return teams } override fun getTeamPlans(): Flow> { - return localRepository.getTeamPlans(userID) + return localRepository.getTeamPlans(currentUserID) } override suspend fun retrieveTeamPlan(teamID: String): Group? { @@ -391,7 +395,7 @@ class UserRepositoryImpl( } private suspend fun getLiveUser(): User? { - val user = localRepository.getUser(userID).firstOrNull() ?: return null + val user = localRepository.getUser(currentUserID).firstOrNull() ?: return null return localRepository.getLiveObject(user) } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/TaskAlarmManager.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/TaskAlarmManager.kt index 1a555169d..e9807a5e0 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/TaskAlarmManager.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/TaskAlarmManager.kt @@ -10,6 +10,7 @@ import com.habitrpg.android.habitica.data.TaskRepository import com.habitrpg.android.habitica.extensions.withImmutableFlag import com.habitrpg.android.habitica.models.tasks.RemindersItem import com.habitrpg.android.habitica.models.tasks.Task +import com.habitrpg.android.habitica.modules.AuthenticationHandler import com.habitrpg.android.habitica.receivers.NotificationPublisher import com.habitrpg.android.habitica.receivers.TaskReceiver import com.habitrpg.common.habitica.helpers.ExceptionHandler @@ -30,7 +31,7 @@ import java.util.Date class TaskAlarmManager( private var context: Context, private var taskRepository: TaskRepository, - private var userId: String + private var authenticationHandler : AuthenticationHandler ) { private val am: AlarmManager? = context.getSystemService(Context.ALARM_SERVICE) as? AlarmManager @@ -68,7 +69,7 @@ class TaskAlarmManager( } suspend fun scheduleAllSavedAlarms(preventDailyReminder: Boolean) { - val tasks = taskRepository.getTaskCopies(userId).firstOrNull() + val tasks = taskRepository.getTaskCopies().firstOrNull() tasks?.forEach { this.setAlarmsForTask(it) } if (!preventDailyReminder) { diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/modules/AppModule.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/modules/AppModule.kt index 92d7634c3..4afb98bc2 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/modules/AppModule.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/modules/AppModule.kt @@ -4,6 +4,7 @@ import android.content.Context import android.content.SharedPreferences import android.content.res.Resources import androidx.preference.PreferenceManager +import com.habitrpg.android.habitica.BuildConfig import com.habitrpg.android.habitica.data.ApiClient import com.habitrpg.android.habitica.data.ContentRepository import com.habitrpg.android.habitica.helpers.AppConfigManager @@ -62,6 +63,17 @@ class AppModule { } else getInstance(context, sharedPreferences, keyStore) } + + @Provides + @Singleton + fun providesAuthenticationHandler(sharedPreferences: SharedPreferences): AuthenticationHandler { + return if (BuildConfig.DEBUG && BuildConfig.TEST_USER_ID.isNotEmpty()) { + AuthenticationHandler(BuildConfig.TEST_USER_ID) + } else { + AuthenticationHandler(sharedPreferences) + } + } + @Provides fun providesResources(@ApplicationContext context: Context): Resources { return context.resources @@ -87,8 +99,4 @@ class AppModule { fun providesRemoteConfigManager(contentRepository: ContentRepository?): AppConfigManager { return AppConfigManager(contentRepository) } - - companion object { - const val NAMED_USER_ID = "userId" - } } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/modules/RepositoryModule.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/modules/RepositoryModule.kt index 9042cb1e9..34759ecb8 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/modules/RepositoryModule.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/modules/RepositoryModule.kt @@ -17,25 +17,27 @@ import io.realm.Realm @Module open class RepositoryModule { @Provides - open fun providesRealm(): Realm? { + open fun providesRealm(): Realm { return Realm.getDefaultInstance() } @Provides - fun providesContentLocalRepository(realm: Realm?): ContentLocalRepository { - return RealmContentLocalRepository(realm!!) + fun providesContentLocalRepository(realm: Realm): ContentLocalRepository { + return RealmContentLocalRepository(realm) } @Provides fun providesContentRepository( contentLocalRepository: ContentLocalRepository, apiClient: ApiClient, - @ApplicationContext context: Context + @ApplicationContext context: Context, + authenticationHandler : AuthenticationHandler ): ContentRepository { return ContentRepositoryImpl( contentLocalRepository, apiClient, - context + context, + authenticationHandler ) } } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/modules/UserModule.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/modules/UserModule.kt index 80d203050..96a61aa3e 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/modules/UserModule.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/modules/UserModule.kt @@ -2,7 +2,6 @@ package com.habitrpg.android.habitica.modules import android.content.Context import android.content.SharedPreferences -import com.habitrpg.android.habitica.BuildConfig import com.habitrpg.android.habitica.data.SocialRepository import com.habitrpg.android.habitica.data.TaskRepository import com.habitrpg.android.habitica.data.UserRepository @@ -13,9 +12,34 @@ import dagger.Provides import dagger.hilt.InstallIn import dagger.hilt.android.qualifiers.ApplicationContext import dagger.hilt.components.SingletonComponent -import javax.inject.Named +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.filterNotNull import javax.inject.Singleton +class AuthenticationHandler { + fun updateUserID(userID: String) { + _userIDFlow.value = userID + } + + private val _userIDFlow = MutableStateFlow(null) + val userIDFlow: Flow = _userIDFlow.filterNotNull() + + val currentUserID: String? + get() = _userIDFlow.value + + val isAuthenticated: Boolean + get() = currentUserID != null + + constructor(sharedPreferences : SharedPreferences) { + _userIDFlow.value = sharedPreferences.getString("UserID", "") ?: "" + } + + constructor(userID: String) { + _userIDFlow.value = userID + } +} + @InstallIn(SingletonComponent::class) @Module class UserModule { @@ -23,30 +47,16 @@ class UserModule { fun providesTaskAlarmManager( @ApplicationContext context: Context, taskRepository: TaskRepository, - @Named(NAMED_USER_ID) userId: String + authenticationHandler: AuthenticationHandler ): TaskAlarmManager { - return TaskAlarmManager(context, taskRepository, userId) - } - - @Provides - @Named(NAMED_USER_ID) - fun providesUserID(sharedPreferences: SharedPreferences): String { - return if (BuildConfig.DEBUG && BuildConfig.TEST_USER_ID.isNotEmpty()) { - BuildConfig.TEST_USER_ID - } else { - sharedPreferences.getString("UserID", "") ?: "" - } + return TaskAlarmManager(context, taskRepository, authenticationHandler) } @Provides @Singleton fun providesUserViewModel( - @Named(NAMED_USER_ID) userID: String, + authenticationHandler: AuthenticationHandler, userRepository: UserRepository, socialRepository: SocialRepository - ) = MainUserViewModel(userID, userRepository, socialRepository) - - companion object { - const val NAMED_USER_ID = "userId" - } + ) = MainUserViewModel(authenticationHandler, userRepository, socialRepository) } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/modules/UserRepositoryModule.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/modules/UserRepositoryModule.kt index d7ac273c7..42d5f90c4 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/modules/UserRepositoryModule.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/modules/UserRepositoryModule.kt @@ -50,77 +50,76 @@ import dagger.hilt.InstallIn import dagger.hilt.android.qualifiers.ApplicationContext import dagger.hilt.components.SingletonComponent import io.realm.Realm -import javax.inject.Named import javax.inject.Singleton @InstallIn(SingletonComponent::class) @Module class UserRepositoryModule { @Provides - fun providesSetupCustomizationRepository(@ApplicationContext context: Context?): SetupCustomizationRepository { - return SetupCustomizationRepositoryImpl(context!!) + fun providesSetupCustomizationRepository(@ApplicationContext context: Context): SetupCustomizationRepository { + return SetupCustomizationRepositoryImpl(context) } @Provides - fun providesTaskLocalRepository(realm: Realm?): TaskLocalRepository { - return RealmTaskLocalRepository(realm!!) + fun providesTaskLocalRepository(realm: Realm): TaskLocalRepository { + return RealmTaskLocalRepository(realm) } @Provides fun providesTaskRepository( localRepository: TaskLocalRepository, apiClient: ApiClient, - @Named(AppModule.NAMED_USER_ID) userId: String, + authenticationHandler : AuthenticationHandler, appConfigManager: AppConfigManager, analyticsManager: AnalyticsManager ): TaskRepository { return TaskRepositoryImpl( localRepository, apiClient, - userId, + authenticationHandler, appConfigManager, analyticsManager ) } @Provides - fun providesTagLocalRepository(realm: Realm?): TagLocalRepository { - return RealmTagLocalRepository(realm!!) + fun providesTagLocalRepository(realm: Realm): TagLocalRepository { + return RealmTagLocalRepository(realm) } @Provides fun providesTagRepository( - localRepository: TagLocalRepository?, - apiClient: ApiClient?, - @Named(AppModule.NAMED_USER_ID) userId: String? + localRepository: TagLocalRepository, + apiClient: ApiClient, + authenticationHandler : AuthenticationHandler ): TagRepository { - return TagRepositoryImpl(localRepository!!, apiClient!!, userId!!) + return TagRepositoryImpl(localRepository, apiClient, authenticationHandler) } @Provides - fun provideChallengeLocalRepository(realm: Realm?): ChallengeLocalRepository { - return RealmChallengeLocalRepository(realm!!) + fun provideChallengeLocalRepository(realm: Realm): ChallengeLocalRepository { + return RealmChallengeLocalRepository(realm) } @Provides fun providesChallengeRepository( - localRepository: ChallengeLocalRepository?, - apiClient: ApiClient?, - @Named(AppModule.NAMED_USER_ID) userId: String? + localRepository: ChallengeLocalRepository, + apiClient: ApiClient, + authenticationHandler : AuthenticationHandler ): ChallengeRepository { - return ChallengeRepositoryImpl(localRepository!!, apiClient!!, userId!!) + return ChallengeRepositoryImpl(localRepository, apiClient, authenticationHandler) } @Provides - fun providesUserLocalRepository(realm: Realm?): UserLocalRepository { - return RealmUserLocalRepository(realm!!) + fun providesUserLocalRepository(realm: Realm): UserLocalRepository { + return RealmUserLocalRepository(realm) } @Provides fun providesUserRepository( localRepository: UserLocalRepository, apiClient: ApiClient, - @Named(AppModule.NAMED_USER_ID) userId: String, + authenticationHandler : AuthenticationHandler, taskRepository: TaskRepository, appConfigManager: AppConfigManager, analyticsManager: AnalyticsManager @@ -128,7 +127,7 @@ class UserRepositoryModule { return UserRepositoryImpl( localRepository, apiClient, - userId, + authenticationHandler, taskRepository, appConfigManager, analyticsManager @@ -136,75 +135,75 @@ class UserRepositoryModule { } @Provides - fun providesSocialLocalRepository(realm: Realm?): SocialLocalRepository { - return RealmSocialLocalRepository(realm!!) + fun providesSocialLocalRepository(realm: Realm): SocialLocalRepository { + return RealmSocialLocalRepository(realm) } @Provides fun providesSocialRepository( - localRepository: SocialLocalRepository?, - apiClient: ApiClient?, - @Named(AppModule.NAMED_USER_ID) userId: String? + localRepository: SocialLocalRepository, + apiClient: ApiClient, + authenticationHandler : AuthenticationHandler ): SocialRepository { - return SocialRepositoryImpl(localRepository!!, apiClient!!, userId!!) + return SocialRepositoryImpl(localRepository, apiClient, authenticationHandler) } @Provides fun providesInventoryLocalRepository( - realm: Realm?): InventoryLocalRepository { - return RealmInventoryLocalRepository(realm!!) + realm: Realm): InventoryLocalRepository { + return RealmInventoryLocalRepository(realm) } @Provides fun providesInventoryRepository( - localRepository: InventoryLocalRepository?, - apiClient: ApiClient?, - @Named(AppModule.NAMED_USER_ID) userId: String?, - remoteConfig: AppConfigManager? + localRepository: InventoryLocalRepository, + apiClient: ApiClient, + authenticationHandler : AuthenticationHandler, + remoteConfig: AppConfigManager ): InventoryRepository { - return InventoryRepositoryImpl(localRepository!!, apiClient!!, userId!!, remoteConfig!!) + return InventoryRepositoryImpl(localRepository, apiClient, authenticationHandler, remoteConfig) } @Provides - fun providesFAQLocalRepository(realm: Realm?): FAQLocalRepository { - return RealmFAQLocalRepository(realm!!) + fun providesFAQLocalRepository(realm: Realm): FAQLocalRepository { + return RealmFAQLocalRepository(realm) } @Provides fun providesFAQRepository( - localRepository: FAQLocalRepository?, - apiClient: ApiClient?, - @Named(AppModule.NAMED_USER_ID) userId: String? + localRepository: FAQLocalRepository, + apiClient: ApiClient, + authenticationHandler : AuthenticationHandler ): FAQRepository { - return FAQRepositoryImpl(localRepository!!, apiClient!!, userId!!) + return FAQRepositoryImpl(localRepository, apiClient, authenticationHandler) } @Provides - fun providesTutorialLocalRepository(realm: Realm?): TutorialLocalRepository { - return RealmTutorialLocalRepository(realm!!) + fun providesTutorialLocalRepository(realm: Realm): TutorialLocalRepository { + return RealmTutorialLocalRepository(realm) } @Provides fun providesTutorialRepository( - localRepository: TutorialLocalRepository?, - apiClient: ApiClient?, - @Named(AppModule.NAMED_USER_ID) userId: String? + localRepository: TutorialLocalRepository, + apiClient: ApiClient, + authenticationHandler : AuthenticationHandler ): TutorialRepository { - return TutorialRepositoryImpl(localRepository!!, apiClient!!, userId!!) + return TutorialRepositoryImpl(localRepository, apiClient, authenticationHandler) } @Provides - fun providesCustomizationLocalRepository(realm: Realm?): CustomizationLocalRepository { - return RealmCustomizationLocalRepository(realm!!) + fun providesCustomizationLocalRepository(realm: Realm): CustomizationLocalRepository { + return RealmCustomizationLocalRepository(realm) } @Provides fun providesCustomizationRepository( - localRepository: CustomizationLocalRepository?, - apiClient: ApiClient?, - @Named(AppModule.NAMED_USER_ID) userId: String? + localRepository: CustomizationLocalRepository, + apiClient: ApiClient, + authenticationHandler : AuthenticationHandler ): CustomizationRepository { - return CustomizationRepositoryImpl(localRepository!!, apiClient!!, userId!!) + return CustomizationRepositoryImpl(localRepository, apiClient, authenticationHandler) } @Provides diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/GroupInviteActivity.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/GroupInviteActivity.kt index 27c23e6b5..7525c1675 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/GroupInviteActivity.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/GroupInviteActivity.kt @@ -12,20 +12,16 @@ import com.google.android.material.tabs.TabLayoutMediator import com.habitrpg.android.habitica.R import com.habitrpg.android.habitica.data.SocialRepository import com.habitrpg.android.habitica.databinding.ActivityPartyInviteBinding -import com.habitrpg.android.habitica.modules.AppModule import com.habitrpg.android.habitica.ui.fragments.social.party.PartyInviteFragment import com.habitrpg.android.habitica.ui.helpers.dismissKeyboard import dagger.hilt.android.AndroidEntryPoint import javax.inject.Inject -import javax.inject.Named @AndroidEntryPoint class GroupInviteActivity : BaseActivity() { private lateinit var binding: ActivityPartyInviteBinding - @field:[Inject Named(AppModule.NAMED_USER_ID)] - lateinit var userId: String @Inject lateinit var socialRepository: SocialRepository diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/HabitButtonWidgetActivity.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/HabitButtonWidgetActivity.kt index fc406de64..8680cd0cc 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/HabitButtonWidgetActivity.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/HabitButtonWidgetActivity.kt @@ -11,7 +11,6 @@ import androidx.recyclerview.widget.LinearLayoutManager import com.habitrpg.android.habitica.R import com.habitrpg.android.habitica.data.TaskRepository import com.habitrpg.android.habitica.databinding.WidgetConfigureHabitButtonBinding -import com.habitrpg.android.habitica.modules.AppModule import com.habitrpg.android.habitica.ui.adapter.SkillTasksRecyclerViewAdapter import com.habitrpg.android.habitica.widget.HabitButtonWidgetProvider import com.habitrpg.common.habitica.helpers.ExceptionHandler @@ -23,7 +22,6 @@ import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.flow.firstOrNull import kotlinx.coroutines.launch import javax.inject.Inject -import javax.inject.Named @AndroidEntryPoint class HabitButtonWidgetActivity : BaseActivity() { @@ -33,8 +31,6 @@ class HabitButtonWidgetActivity : BaseActivity() { @Inject lateinit var taskRepository: TaskRepository - @field:[Inject Named(AppModule.NAMED_USER_ID)] - lateinit var userId: String private var widgetId: Int = 0 private var adapter: SkillTasksRecyclerViewAdapter? = null @@ -78,7 +74,7 @@ class HabitButtonWidgetActivity : BaseActivity() { binding.recyclerView.adapter = adapter CoroutineScope(Dispatchers.Main + job).launch(ExceptionHandler.coroutine()) { - adapter?.data = taskRepository.getTasks(TaskType.HABIT, userId, emptyArray()).firstOrNull() ?: listOf() + adapter?.data = taskRepository.getTasks(TaskType.HABIT, includedGroupIDs = emptyArray()).firstOrNull() ?: listOf() } } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/SkillTasksActivity.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/SkillTasksActivity.kt index fbd500c0c..185618096 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/SkillTasksActivity.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/SkillTasksActivity.kt @@ -18,7 +18,6 @@ import com.habitrpg.android.habitica.ui.fragments.skills.SkillTasksRecyclerViewF import com.habitrpg.shared.habitica.models.tasks.TaskType import dagger.hilt.android.AndroidEntryPoint import javax.inject.Inject -import javax.inject.Named @AndroidEntryPoint class SkillTasksActivity : BaseActivity() { @@ -26,8 +25,6 @@ class SkillTasksActivity : BaseActivity() { @Inject lateinit var taskRepository: TaskRepository - @field:[Inject Named(AppModule.NAMED_USER_ID)] - lateinit var userId: String internal var viewFragmentsDictionary = SparseArray() diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/TaskFormActivity.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/TaskFormActivity.kt index 90b923dc1..4a52b5d7e 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/TaskFormActivity.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/TaskFormActivity.kt @@ -34,7 +34,6 @@ import androidx.core.view.iterator import androidx.core.widget.NestedScrollView import androidx.lifecycle.lifecycleScope import com.habitrpg.android.habitica.R -import com.habitrpg.android.habitica.components.UserComponent import com.habitrpg.android.habitica.data.ChallengeRepository import com.habitrpg.android.habitica.data.SocialRepository import com.habitrpg.android.habitica.data.TagRepository diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/NavigationDrawerAdapter.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/NavigationDrawerAdapter.kt index 055c3517d..f258e9258 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/NavigationDrawerAdapter.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/NavigationDrawerAdapter.kt @@ -44,8 +44,10 @@ class NavigationDrawerAdapter(tintColor: Int, backgroundTintColor: Int) : Recycl internal val items: MutableList = ArrayList() var selectedItem: Int? = null set(value) { + val oldValue = field field = value - notifyDataSetChanged() + oldValue?.let { notifyItemChanged(it) } + value?.let { notifyItemChanged(it) } } var itemSelectedEvents: ((HabiticaDrawerItem) -> Unit)? = null diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/ShopRecyclerAdapter.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/ShopRecyclerAdapter.kt index 3729bdaa7..ccfb8ce5d 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/ShopRecyclerAdapter.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/ShopRecyclerAdapter.kt @@ -144,6 +144,7 @@ class ShopRecyclerAdapter : androidx.recyclerview.widget.RecyclerView.Adapter() { - @field:[Inject Named(AppModule.NAMED_USER_ID)] - lateinit var userId: String - @Inject lateinit var appConfigManager: AppConfigManager diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/PromoWebFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/PromoWebFragment.kt index 618a07752..c9f032f36 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/PromoWebFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/PromoWebFragment.kt @@ -6,17 +6,15 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.webkit.WebChromeClient -import com.habitrpg.android.habitica.components.UserComponent import com.habitrpg.android.habitica.databinding.FragmentNewsBinding -import com.habitrpg.android.habitica.modules.AppModule -import javax.inject.Inject -import javax.inject.Named +import com.habitrpg.android.habitica.ui.viewmodels.MainUserViewModel import dagger.hilt.android.AndroidEntryPoint +import javax.inject.Inject @AndroidEntryPoint class PromoWebFragment : BaseMainFragment() { - @field:[Inject Named(AppModule.NAMED_USER_ID)] - lateinit var userID: String + @Inject + lateinit var userViewModel: MainUserViewModel override var binding: FragmentNewsBinding? = null @@ -44,7 +42,7 @@ class PromoWebFragment : BaseMainFragment() { arguments?.let { val args = PromoWebFragmentArgs.fromBundle(it) var url = args.url - url = url.replace("USER_ID", userID) + url = url.replace("USER_ID", userViewModel.userID) binding?.newsWebview?.loadUrl(url) } } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/items/ItemDialogFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/items/ItemDialogFragment.kt index e265894a9..b07cfeb11 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/items/ItemDialogFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/items/ItemDialogFragment.kt @@ -7,7 +7,6 @@ import android.view.ViewGroup import android.view.Window import androidx.lifecycle.lifecycleScope import com.habitrpg.android.habitica.R -import com.habitrpg.android.habitica.components.UserComponent import com.habitrpg.android.habitica.data.InventoryRepository import com.habitrpg.android.habitica.data.SocialRepository import com.habitrpg.android.habitica.data.UserRepository diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/items/ItemRecyclerFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/items/ItemRecyclerFragment.kt index 559079e30..8e943863a 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/items/ItemRecyclerFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/items/ItemRecyclerFragment.kt @@ -11,7 +11,6 @@ import androidx.core.os.bundleOf import androidx.lifecycle.lifecycleScope import androidx.swiperefreshlayout.widget.SwipeRefreshLayout import com.habitrpg.android.habitica.R -import com.habitrpg.android.habitica.components.UserComponent import com.habitrpg.android.habitica.data.InventoryRepository import com.habitrpg.android.habitica.data.SocialRepository import com.habitrpg.android.habitica.data.UserRepository diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/shops/ShopFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/shops/ShopFragment.kt index 2f41ec2b9..26e2a01de 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/shops/ShopFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/shops/ShopFragment.kt @@ -27,6 +27,7 @@ import com.habitrpg.android.habitica.ui.helpers.SafeDefaultItemAnimator import com.habitrpg.android.habitica.ui.viewmodels.MainUserViewModel import com.habitrpg.android.habitica.ui.views.CurrencyText import com.habitrpg.android.habitica.ui.views.dialogs.HabiticaAlertDialog +import com.habitrpg.android.habitica.ui.views.getTranslatedClassName import com.habitrpg.android.habitica.ui.views.shops.PurchaseDialog import com.habitrpg.common.habitica.helpers.ExceptionHandler import com.habitrpg.common.habitica.helpers.RecyclerViewState @@ -202,10 +203,11 @@ open class ShopFragment : BaseMainFragment() private fun showClassChangeDialog(classIdentifier: String) { context?.let { context -> val alert = HabiticaAlertDialog(context) - alert.setTitle(getString(R.string.class_confirmation_price, classIdentifier, 3)) + alert.setTitle(getString(R.string.class_confirmation_price, getTranslatedClassName(requireContext().resources, classIdentifier), 3)) alert.addButton(R.string.choose_class, true) { _, _ -> lifecycleScope.launch(ExceptionHandler.coroutine()) { userRepository.changeClass(classIdentifier) + adapter?.notifyDataSetChanged() } } alert.addButton(R.string.dialog_go_back, false) diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/preferences/PreferencesFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/preferences/PreferencesFragment.kt index 8ebf7b4fe..85f3493e5 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/preferences/PreferencesFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/preferences/PreferencesFragment.kt @@ -18,6 +18,7 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.res.colorResource import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp @@ -622,34 +623,40 @@ fun PauseResumeDamageView( Text( stringResource(R.string.pause_damage_1_title), color = HabiticaTheme.colors.textPrimary, + fontWeight = FontWeight.Normal, fontSize = 16.sp ) Text( stringResource(R.string.pause_damage_1_description), color = HabiticaTheme.colors.textSecondary, fontSize = 14.sp, + fontWeight = FontWeight.Normal, modifier = Modifier.padding(bottom = 12.dp) ) Text( stringResource(R.string.pause_damage_2_title), color = HabiticaTheme.colors.textPrimary, + fontWeight = FontWeight.Normal, fontSize = 16.sp ) Text( stringResource(R.string.pause_damage_2_description), color = HabiticaTheme.colors.textSecondary, fontSize = 14.sp, + fontWeight = FontWeight.Normal, modifier = Modifier.padding(bottom = 12.dp) ) Text( stringResource(R.string.pause_damage_3_title), color = HabiticaTheme.colors.textPrimary, + fontWeight = FontWeight.Normal, fontSize = 16.sp ) Text( stringResource(R.string.pause_damage_3_description), color = HabiticaTheme.colors.textSecondary, fontSize = 14.sp, + fontWeight = FontWeight.Normal, modifier = Modifier.padding(bottom = 18.dp) ) HabiticaButton( diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/purchases/GemsPurchaseFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/purchases/GemsPurchaseFragment.kt index 6d5676be9..3f2e1976b 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/purchases/GemsPurchaseFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/purchases/GemsPurchaseFragment.kt @@ -15,7 +15,6 @@ import androidx.fragment.app.Fragment import androidx.lifecycle.lifecycleScope import com.android.billingclient.api.ProductDetails import com.habitrpg.android.habitica.R -import com.habitrpg.android.habitica.components.UserComponent import com.habitrpg.android.habitica.data.UserRepository import com.habitrpg.android.habitica.databinding.FragmentGemPurchaseBinding import com.habitrpg.android.habitica.extensions.addCancelButton diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/purchases/GiftBalanceGemsFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/purchases/GiftBalanceGemsFragment.kt index 858cafed3..870f11308 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/purchases/GiftBalanceGemsFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/purchases/GiftBalanceGemsFragment.kt @@ -8,7 +8,6 @@ import android.view.ViewGroup import androidx.core.view.isVisible import androidx.lifecycle.lifecycleScope import com.habitrpg.android.habitica.R -import com.habitrpg.android.habitica.components.UserComponent import com.habitrpg.android.habitica.data.SocialRepository import com.habitrpg.android.habitica.data.UserRepository import com.habitrpg.android.habitica.databinding.FragmentGiftGemBalanceBinding diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/purchases/GiftPurchaseGemsFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/purchases/GiftPurchaseGemsFragment.kt index a8a11c62f..5f539df2c 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/purchases/GiftPurchaseGemsFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/purchases/GiftPurchaseGemsFragment.kt @@ -6,7 +6,6 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import com.android.billingclient.api.ProductDetails -import com.habitrpg.android.habitica.components.UserComponent import com.habitrpg.android.habitica.data.SocialRepository import com.habitrpg.android.habitica.databinding.FragmentGiftGemPurchaseBinding import com.habitrpg.android.habitica.helpers.PurchaseHandler diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/purchases/SubscriptionFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/purchases/SubscriptionFragment.kt index c23938c86..c9df79001 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/purchases/SubscriptionFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/purchases/SubscriptionFragment.kt @@ -16,7 +16,6 @@ import androidx.fragment.app.Fragment import androidx.lifecycle.lifecycleScope import com.android.billingclient.api.ProductDetails import com.habitrpg.android.habitica.R -import com.habitrpg.android.habitica.components.UserComponent import com.habitrpg.android.habitica.data.InventoryRepository import com.habitrpg.android.habitica.data.UserRepository import com.habitrpg.android.habitica.databinding.FragmentSubscriptionBinding diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/setup/AvatarSetupFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/setup/AvatarSetupFragment.kt index f3c9199fb..721d841fd 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/setup/AvatarSetupFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/setup/AvatarSetupFragment.kt @@ -10,7 +10,6 @@ import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.LinearLayoutManager import com.google.android.material.tabs.TabLayout import com.habitrpg.android.habitica.R -import com.habitrpg.android.habitica.components.UserComponent import com.habitrpg.android.habitica.data.InventoryRepository import com.habitrpg.android.habitica.data.SetupCustomizationRepository import com.habitrpg.android.habitica.data.UserRepository diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/setup/IntroFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/setup/IntroFragment.kt index 449e811b2..b4f6f17b8 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/setup/IntroFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/setup/IntroFragment.kt @@ -5,7 +5,6 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import com.habitrpg.android.habitica.components.UserComponent import com.habitrpg.android.habitica.databinding.FragmentIntroBinding import com.habitrpg.android.habitica.ui.fragments.BaseFragment import dagger.hilt.android.AndroidEntryPoint diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/setup/TaskSetupFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/setup/TaskSetupFragment.kt index 2b7995660..c80db83e3 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/setup/TaskSetupFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/setup/TaskSetupFragment.kt @@ -7,7 +7,6 @@ import android.view.View import android.view.ViewGroup import androidx.recyclerview.widget.GridLayoutManager import com.habitrpg.android.habitica.R -import com.habitrpg.android.habitica.components.UserComponent import com.habitrpg.android.habitica.databinding.FragmentSetupTasksBinding import com.habitrpg.android.habitica.models.tasks.Days import com.habitrpg.android.habitica.models.tasks.Task diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/setup/WelcomeFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/setup/WelcomeFragment.kt index 221c4e7b3..369d13b45 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/setup/WelcomeFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/setup/WelcomeFragment.kt @@ -10,7 +10,6 @@ import android.view.ViewGroup import androidx.core.content.ContextCompat import androidx.lifecycle.lifecycleScope import com.habitrpg.android.habitica.R -import com.habitrpg.android.habitica.components.UserComponent import com.habitrpg.android.habitica.data.UserRepository import com.habitrpg.android.habitica.databinding.FragmentWelcomeBinding import com.habitrpg.android.habitica.extensions.OnChangeTextWatcher diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/skills/SkillTasksRecyclerViewFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/skills/SkillTasksRecyclerViewFragment.kt index bdf166574..b2fea98d0 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/skills/SkillTasksRecyclerViewFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/skills/SkillTasksRecyclerViewFragment.kt @@ -6,7 +6,6 @@ import android.view.View import android.view.ViewGroup import androidx.lifecycle.asLiveData import androidx.recyclerview.widget.LinearLayoutManager -import com.habitrpg.android.habitica.components.UserComponent import com.habitrpg.android.habitica.data.TaskRepository import com.habitrpg.android.habitica.databinding.FragmentRecyclerviewBinding import com.habitrpg.android.habitica.models.tasks.Task diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/QuestDetailFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/QuestDetailFragment.kt index 9ff3b84fd..27c5e3dfe 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/QuestDetailFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/QuestDetailFragment.kt @@ -12,7 +12,6 @@ import androidx.core.content.ContextCompat import androidx.core.text.toHtml import androidx.lifecycle.lifecycleScope import com.habitrpg.android.habitica.R -import com.habitrpg.android.habitica.components.UserComponent import com.habitrpg.android.habitica.data.InventoryRepository import com.habitrpg.android.habitica.data.SocialRepository import com.habitrpg.android.habitica.databinding.FragmentQuestDetailBinding @@ -37,7 +36,6 @@ import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch import javax.inject.Inject -import javax.inject.Named import dagger.hilt.android.AndroidEntryPoint @AndroidEntryPoint @@ -49,9 +47,6 @@ class QuestDetailFragment : BaseMainFragment() { @Inject lateinit var inventoryRepository: InventoryRepository - @field:[Inject Named(AppModule.NAMED_USER_ID)] - lateinit var userId: String - @Inject lateinit var userViewModel: MainUserViewModel @@ -123,7 +118,7 @@ class QuestDetailFragment : BaseMainFragment() { val user = userViewModel.user.value if (binding?.questResponseWrapper != null) { - if (userId != party?.quest?.leader && user?.party?.quest?.key == group.quest?.key && user?.party?.quest?.RSVPNeeded == false) { + if (userViewModel.userID != party?.quest?.leader && user?.party?.quest?.key == group.quest?.key && user?.party?.quest?.RSVPNeeded == false) { binding?.questLeaveButton?.visibility = View.VISIBLE } else { binding?.questLeaveButton?.visibility = View.GONE @@ -143,7 +138,7 @@ class QuestDetailFragment : BaseMainFragment() { } private fun showLeaderButtons(): Boolean { - return userId == party?.quest?.leader || userId == party?.leaderID + return userViewModel.userID == party?.quest?.leader || userViewModel.userID == party?.leaderID } private fun updateQuestContent(questContent: QuestContent) { diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/TavernDetailFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/TavernDetailFragment.kt index d367293a5..2a176b549 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/TavernDetailFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/TavernDetailFragment.kt @@ -13,7 +13,6 @@ import androidx.appcompat.app.AlertDialog import androidx.core.content.ContextCompat import androidx.lifecycle.lifecycleScope import com.habitrpg.android.habitica.R -import com.habitrpg.android.habitica.components.UserComponent import com.habitrpg.android.habitica.data.InventoryRepository import com.habitrpg.android.habitica.data.SocialRepository import com.habitrpg.android.habitica.data.UserRepository diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/TavernFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/TavernFragment.kt index ff9ef6571..5a2a04100 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/TavernFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/TavernFragment.kt @@ -12,7 +12,6 @@ import androidx.fragment.app.viewModels import androidx.viewpager2.adapter.FragmentStateAdapter import com.google.android.material.tabs.TabLayoutMediator import com.habitrpg.android.habitica.R -import com.habitrpg.android.habitica.components.UserComponent import com.habitrpg.android.habitica.data.SocialRepository import com.habitrpg.android.habitica.databinding.FragmentViewpagerBinding import com.habitrpg.android.habitica.models.social.Group diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/challenges/ChallengeListFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/challenges/ChallengeListFragment.kt index 4675d3c38..7e0641c05 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/challenges/ChallengeListFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/challenges/ChallengeListFragment.kt @@ -7,7 +7,6 @@ import android.view.ViewGroup import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.RecyclerView import com.habitrpg.android.habitica.R -import com.habitrpg.android.habitica.components.UserComponent import com.habitrpg.android.habitica.data.ChallengeRepository import com.habitrpg.android.habitica.data.SocialRepository import com.habitrpg.android.habitica.data.UserRepository @@ -15,18 +14,17 @@ import com.habitrpg.android.habitica.databinding.FragmentRefreshRecyclerviewBind import com.habitrpg.android.habitica.helpers.MainNavigationController import com.habitrpg.android.habitica.models.social.Challenge import com.habitrpg.android.habitica.models.social.Group -import com.habitrpg.android.habitica.modules.AppModule import com.habitrpg.android.habitica.ui.adapter.social.ChallengesListViewAdapter import com.habitrpg.android.habitica.ui.fragments.BaseFragment import com.habitrpg.android.habitica.ui.helpers.SafeDefaultItemAnimator +import com.habitrpg.android.habitica.ui.viewmodels.MainUserViewModel import com.habitrpg.common.habitica.helpers.EmptyItem import com.habitrpg.common.habitica.helpers.ExceptionHandler import com.habitrpg.common.habitica.helpers.launchCatching +import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.flow.combine import kotlinx.coroutines.launch import javax.inject.Inject -import javax.inject.Named -import dagger.hilt.android.AndroidEntryPoint @AndroidEntryPoint class ChallengeListFragment : @@ -35,15 +33,12 @@ class ChallengeListFragment : @Inject lateinit var challengeRepository: ChallengeRepository - @Inject lateinit var socialRepository: SocialRepository - @Inject lateinit var userRepository: UserRepository - - @field:[Inject Named(AppModule.NAMED_USER_ID)] - lateinit var userId: String + @Inject + lateinit var userViewModel: MainUserViewModel override var binding: FragmentRefreshRecyclerviewBinding? = null @@ -77,7 +72,7 @@ class ChallengeListFragment : override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - challengeAdapter = ChallengesListViewAdapter(viewUserChallengesOnly, userId) + challengeAdapter = ChallengesListViewAdapter(viewUserChallengesOnly, userViewModel.userID) challengeAdapter?.onOpenChallengeFragment = { openDetailFragment(it) } binding?.refreshLayout?.setOnRefreshListener(this) diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/challenges/ChallengesOverviewFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/challenges/ChallengesOverviewFragment.kt index 9c5d35a35..6d55687c0 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/challenges/ChallengesOverviewFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/challenges/ChallengesOverviewFragment.kt @@ -15,7 +15,6 @@ import androidx.fragment.app.Fragment import androidx.viewpager2.adapter.FragmentStateAdapter import com.google.android.material.tabs.TabLayoutMediator import com.habitrpg.android.habitica.R -import com.habitrpg.android.habitica.components.UserComponent import com.habitrpg.android.habitica.data.ChallengeRepository import com.habitrpg.android.habitica.databinding.FragmentViewpagerBinding import com.habitrpg.android.habitica.ui.activities.ChallengeFormActivity diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/guilds/GuildListFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/guilds/GuildListFragment.kt index 8aab2ff17..7ef48688b 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/guilds/GuildListFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/guilds/GuildListFragment.kt @@ -8,7 +8,6 @@ import androidx.appcompat.widget.SearchView import androidx.lifecycle.lifecycleScope import androidx.swiperefreshlayout.widget.SwipeRefreshLayout import com.habitrpg.android.habitica.R -import com.habitrpg.android.habitica.components.UserComponent import com.habitrpg.android.habitica.data.SocialRepository import com.habitrpg.android.habitica.databinding.FragmentRefreshRecyclerviewBinding import com.habitrpg.android.habitica.ui.adapter.social.GuildListAdapter diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/guilds/GuildOverviewFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/guilds/GuildOverviewFragment.kt index e339993cf..272f5b5e9 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/guilds/GuildOverviewFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/guilds/GuildOverviewFragment.kt @@ -16,7 +16,6 @@ import androidx.fragment.app.Fragment import androidx.viewpager2.adapter.FragmentStateAdapter import com.google.android.material.tabs.TabLayoutMediator import com.habitrpg.android.habitica.R -import com.habitrpg.android.habitica.components.UserComponent import com.habitrpg.android.habitica.data.SocialRepository import com.habitrpg.android.habitica.databinding.FragmentViewpagerBinding import com.habitrpg.android.habitica.extensions.addCloseButton diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/party/PartyDetailFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/party/PartyDetailFragment.kt index a97e204a5..b5723a0cc 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/party/PartyDetailFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/party/PartyDetailFragment.kt @@ -12,7 +12,6 @@ import androidx.core.os.bundleOf import androidx.core.view.isVisible import androidx.lifecycle.lifecycleScope import com.habitrpg.android.habitica.R -import com.habitrpg.android.habitica.components.UserComponent import com.habitrpg.android.habitica.data.ChallengeRepository import com.habitrpg.android.habitica.data.InventoryRepository import com.habitrpg.android.habitica.data.SocialRepository @@ -26,7 +25,6 @@ import com.habitrpg.android.habitica.models.members.Member import com.habitrpg.android.habitica.models.social.Challenge import com.habitrpg.android.habitica.models.social.Group import com.habitrpg.android.habitica.models.user.User -import com.habitrpg.android.habitica.modules.AppModule import com.habitrpg.android.habitica.ui.activities.FullProfileActivity import com.habitrpg.android.habitica.ui.activities.MainActivity import com.habitrpg.android.habitica.ui.fragments.BaseFragment @@ -43,13 +41,12 @@ import com.habitrpg.common.habitica.helpers.ExceptionHandler import com.habitrpg.common.habitica.helpers.launchCatching import com.habitrpg.common.habitica.helpers.setMarkdown import com.habitrpg.common.habitica.views.AvatarView +import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.delay import kotlinx.coroutines.flow.firstOrNull import kotlinx.coroutines.launch import javax.inject.Inject -import javax.inject.Named -import dagger.hilt.android.AndroidEntryPoint @AndroidEntryPoint class PartyDetailFragment : BaseFragment() { @@ -74,10 +71,6 @@ class PartyDetailFragment : BaseFragment() { @Inject lateinit var inventoryRepository: InventoryRepository - @field:[Inject Named(AppModule.NAMED_USER_ID)] - lateinit var userId: String - - override fun onDestroyView() { inventoryRepository.close() super.onDestroyView() @@ -252,7 +245,7 @@ class PartyDetailFragment : BaseFragment() { binding?.questProgressView?.setData(questContent, viewModel?.getGroupData()?.value?.quest?.progress) val questParticipants = viewModel?.getGroupData()?.value?.quest?.members - if (questParticipants?.find { it.key == userId } != null) { + if (questParticipants?.find { it.key == viewModel?.userViewModel?.userID } != null) { binding?.questParticipationView?.text = context?.getString(R.string.number_participants, questParticipants.size) } else { binding?.questParticipationView?.text = context?.getString(R.string.not_participating) @@ -286,13 +279,13 @@ class PartyDetailFragment : BaseFragment() { FullProfileActivity.open(member.id ?: "") } viewHolder.sendMessageEvent = { - member.id?.let { showSendMessageToUserDialog(it, member.displayName) } + member.id.let { showSendMessageToUserDialog(it, member.displayName) } } viewHolder.transferOwnershipEvent = { - member.id?.let { showTransferOwnerShipDialog(it, member.displayName) } + member.id.let { showTransferOwnerShipDialog(it, member.displayName) } } viewHolder.removeMemberEvent = { - member.id?.let { showRemoveMemberDialog(it, member.displayName) } + member.id.let { showRemoveMemberDialog(it, member.displayName) } } } } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/party/PartySeekingFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/party/PartySeekingFragment.kt index 25031705a..63c56a07f 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/party/PartySeekingFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/party/PartySeekingFragment.kt @@ -81,6 +81,7 @@ class PartySeekingViewModel @Inject constructor( seekingUsers = Pager( config = PagingConfig( pageSize = 30, + prefetchDistance = 10 ), pagingSourceFactory = { PartySeekingPagingSource(socialRepository) @@ -250,8 +251,7 @@ fun PartySeekingView( textAlign = TextAlign.Center, color = HabiticaTheme.colors.textSecondary, modifier = Modifier .width(250.dp) - .align(alignment = Alignment.CenterHorizontally) - ) + .align(alignment = Alignment.CenterHorizontally)) } } } else { @@ -276,6 +276,7 @@ fun PartySeekingView( ) } } + } items( items = pageData ) { @@ -329,10 +330,10 @@ fun PartySeekingView( Box( modifier = Modifier .fillMaxWidth() - .padding(8.dp), + .padding(12.dp), contentAlignment = Alignment.Center ) { - HabiticaCircularProgressView() + HabiticaCircularProgressView(indicatorSize = 32.dp) } } } @@ -367,7 +368,7 @@ class PartySeekingPagingSource( LoadResult.Page( data = response ?: emptyList(), prevKey = if (page == 0) null else page.minus(1), - nextKey = if (response?.isEmpty() != false) null else page.plus(1), + nextKey = if ((response?.size ?: 0) < 30) null else page.plus(1), ) } catch (e : Exception) { LoadResult.Error(e) diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/support/BugFixFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/support/BugFixFragment.kt index c126b0b22..1d89c7627 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/support/BugFixFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/support/BugFixFragment.kt @@ -15,7 +15,6 @@ import com.habitrpg.android.habitica.databinding.FragmentSupportBugFixBinding import com.habitrpg.android.habitica.databinding.KnownIssueBinding import com.habitrpg.android.habitica.helpers.AppConfigManager import com.habitrpg.android.habitica.helpers.MainNavigationController -import com.habitrpg.android.habitica.modules.AppModule import com.habitrpg.android.habitica.ui.fragments.BaseMainFragment import com.habitrpg.android.habitica.ui.viewmodels.MainUserViewModel import com.habitrpg.common.habitica.extensions.layoutInflater @@ -25,7 +24,6 @@ import com.jaredrummler.android.device.DeviceName import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.launch import javax.inject.Inject -import javax.inject.Named @AndroidEntryPoint class BugFixFragment : BaseMainFragment() { @@ -39,9 +37,6 @@ class BugFixFragment : BaseMainFragment() { return FragmentSupportBugFixBinding.inflate(inflater, container, false) } - @field:[Inject Named(AppModule.NAMED_USER_ID)] - lateinit var userId: String - @Inject lateinit var appConfigManager: AppConfigManager @Inject @@ -121,7 +116,7 @@ class BugFixFragment : BaseMainFragment() { if (appConfigManager.testingLevel().name != AppTestingLevel.PRODUCTION.name) { bodyOfEmail += newLine + Uri.encode(appConfigManager.testingLevel().name) } - bodyOfEmail += newLine + Uri.encode("User ID: $userId") + bodyOfEmail += newLine + Uri.encode("User ID: $userViewModel.userID") userViewModel.user.value?.let { user -> bodyOfEmail += newLine + Uri.encode("Level: " + (user.stats?.lvl ?: 0)) + diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/support/FAQDetailFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/support/FAQDetailFragment.kt index c6fadb57a..822ad458d 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/support/FAQDetailFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/support/FAQDetailFragment.kt @@ -6,7 +6,6 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.lifecycle.lifecycleScope -import com.habitrpg.android.habitica.components.UserComponent import com.habitrpg.android.habitica.data.FAQRepository import com.habitrpg.android.habitica.databinding.FragmentFaqDetailBinding import com.habitrpg.android.habitica.ui.fragments.BaseMainFragment diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/support/FAQOverviewFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/support/FAQOverviewFragment.kt index cd044ffe2..3dfd60305 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/support/FAQOverviewFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/support/FAQOverviewFragment.kt @@ -9,7 +9,6 @@ import android.widget.ImageView import androidx.core.os.bundleOf import androidx.lifecycle.lifecycleScope import com.habitrpg.android.habitica.R -import com.habitrpg.android.habitica.components.UserComponent import com.habitrpg.android.habitica.data.FAQRepository import com.habitrpg.android.habitica.databinding.FragmentFaqOverviewBinding import com.habitrpg.android.habitica.databinding.SupportFaqItemBinding diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/support/SupportMainFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/support/SupportMainFragment.kt index 5f6c28610..2bedaed12 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/support/SupportMainFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/support/SupportMainFragment.kt @@ -12,14 +12,12 @@ import com.habitrpg.android.habitica.data.FAQRepository import com.habitrpg.android.habitica.databinding.FragmentSupportMainBinding import com.habitrpg.android.habitica.helpers.AppConfigManager import com.habitrpg.android.habitica.helpers.MainNavigationController -import com.habitrpg.android.habitica.modules.AppModule import com.habitrpg.android.habitica.ui.fragments.BaseMainFragment import com.habitrpg.android.habitica.ui.views.HabiticaSnackbar import com.habitrpg.common.habitica.helpers.ExceptionHandler +import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.launch import javax.inject.Inject -import javax.inject.Named -import dagger.hilt.android.AndroidEntryPoint @AndroidEntryPoint class SupportMainFragment : BaseMainFragment() { @@ -29,8 +27,6 @@ class SupportMainFragment : BaseMainFragment() { return FragmentSupportMainBinding.inflate(inflater, container, false) } - @field:[Inject Named(AppModule.NAMED_USER_ID)] - lateinit var userId: String @Inject lateinit var faqRepository: FAQRepository @Inject diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/SectionViewHolder.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/SectionViewHolder.kt index 57ec3c1da..e50e78071 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/SectionViewHolder.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/SectionViewHolder.kt @@ -22,6 +22,7 @@ class SectionViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { private val selectionSpinner: Spinner? = itemView.findViewById(R.id.classSelectionSpinner) val switchClassButton: LinearLayout? = itemView.findViewById(R.id.change_class_button) val switchClassLabel: TextView? = itemView.findViewById(R.id.change_class_label) + val switchClassDescription: TextView? = itemView.findViewById(R.id.change_class_description) val switchClassCurrency: CurrencyView? = itemView.findViewById(R.id.change_class_currency_view) internal val notesView: TextView? = itemView.findViewById(R.id.headerNotesView) private val countPill: TextView? = itemView.findViewById(R.id.count_pill) diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewmodels/AuthenticationViewModel.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewmodels/AuthenticationViewModel.kt index 7adc78f79..385812743 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewmodels/AuthenticationViewModel.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewmodels/AuthenticationViewModel.kt @@ -20,6 +20,7 @@ import com.habitrpg.android.habitica.R import com.habitrpg.android.habitica.data.ApiClient import com.habitrpg.android.habitica.data.UserRepository import com.habitrpg.android.habitica.extensions.addCloseButton +import com.habitrpg.android.habitica.modules.AuthenticationHandler import com.habitrpg.android.habitica.ui.views.dialogs.HabiticaAlertDialog import com.habitrpg.common.habitica.api.HostConfig import com.habitrpg.common.habitica.helpers.AnalyticsManager @@ -34,6 +35,7 @@ class AuthenticationViewModel @Inject constructor( val apiClient : ApiClient, val userRepository : UserRepository, val sharedPrefs : SharedPreferences, + val authenticationHandler : AuthenticationHandler, val hostConfig : HostConfig, val analyticsManager : AnalyticsManager, private val keyHelper : KeyHelper? @@ -142,6 +144,7 @@ class AuthenticationViewModel @Inject constructor( @Throws(Exception::class) private fun saveTokens(api : String, user : String) { this.apiClient.updateAuthenticationCredentials(user, api) + authenticationHandler.updateUserID(user) sharedPrefs.edit { putString("UserID", user) val encryptedKey = diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewmodels/MainUserViewModel.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewmodels/MainUserViewModel.kt index 05cf1376a..bf1346261 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewmodels/MainUserViewModel.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewmodels/MainUserViewModel.kt @@ -8,6 +8,7 @@ import com.habitrpg.android.habitica.data.UserRepository import com.habitrpg.android.habitica.models.TeamPlan import com.habitrpg.android.habitica.models.members.Member import com.habitrpg.android.habitica.models.user.User +import com.habitrpg.android.habitica.modules.AuthenticationHandler import com.habitrpg.common.habitica.helpers.ExceptionHandler import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.MainScope @@ -19,12 +20,12 @@ import kotlinx.coroutines.flow.flatMapLatest import kotlinx.coroutines.launch import javax.inject.Inject -class MainUserViewModel @Inject constructor(private val providedUserID: String, val userRepository: UserRepository, val socialRepository: SocialRepository) { +class MainUserViewModel @Inject constructor(private val authenticationHandler : AuthenticationHandler, val userRepository: UserRepository, val socialRepository: SocialRepository) { val formattedUsername: CharSequence? get() = user.value?.formattedUsername val userID: String - get() = user.value?.id ?: providedUserID + get() = user.value?.id ?: authenticationHandler.currentUserID ?: "" val username: CharSequence get() = user.value?.username ?: "" val displayName: CharSequence diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/dialogs/HabiticaAlertDialog.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/dialogs/HabiticaAlertDialog.kt index a629737ed..16d4904b3 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/dialogs/HabiticaAlertDialog.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/dialogs/HabiticaAlertDialog.kt @@ -14,6 +14,7 @@ import android.widget.Button import android.widget.LinearLayout import android.widget.RelativeLayout import androidx.appcompat.app.AlertDialog +import androidx.appcompat.app.AppCompatActivity import androidx.core.content.ContextCompat import androidx.core.view.children import androidx.lifecycle.lifecycleScope @@ -24,7 +25,9 @@ import com.habitrpg.android.habitica.ui.activities.BaseActivity import com.habitrpg.common.habitica.extensions.dpToPx import com.habitrpg.common.habitica.extensions.layoutInflater import com.plattysoft.leonids.ParticleSystem +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.MainScope import kotlinx.coroutines.delay import kotlinx.coroutines.launch import java.lang.ref.WeakReference @@ -68,6 +71,17 @@ open class HabiticaAlertDialog(context: Context) : AlertDialog(context, R.style. binding.dialogWrapper.layoutParams = layoutParams } + // Used when a dialog has an action that neeeds to complete even when the dialog is alrady closed + val longLivingScope: CoroutineScope + get() { + val activity = getActivity() + return if (activity is AppCompatActivity) { + activity.lifecycleScope + } else { + MainScope() + } + } + init { setView(binding.root) binding.closeButton.setOnClickListener { dismiss() } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/dialogs/PetSuggestHatchDialog.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/dialogs/PetSuggestHatchDialog.kt index cf44b9864..ea7e754f9 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/dialogs/PetSuggestHatchDialog.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/dialogs/PetSuggestHatchDialog.kt @@ -15,12 +15,10 @@ import com.habitrpg.android.habitica.models.inventory.Animal import com.habitrpg.android.habitica.models.inventory.Egg import com.habitrpg.android.habitica.models.inventory.HatchingPotion import com.habitrpg.android.habitica.models.inventory.Item -import com.habitrpg.android.habitica.ui.activities.BaseActivity import com.habitrpg.android.habitica.ui.activities.MainActivity import com.habitrpg.common.habitica.extensions.DataBindingUtils import com.habitrpg.common.habitica.extensions.loadImage import com.habitrpg.common.habitica.helpers.launchCatching -import kotlinx.coroutines.MainScope import java.util.Locale import javax.inject.Inject @@ -136,16 +134,20 @@ class PetSuggestHatchDialog(context: Context) : HabiticaAlertDialog(context) { val activity = (getActivity() as? MainActivity) ?: return@addButton val thisPotion = potion ?: return@addButton val thisEgg = egg ?: return@addButton - lifecycleScope.launchCatching { - if (!hasEgg) { - activity.inventoryRepository.purchaseItem("eggs", thisEgg.key, 1) + longLivingScope.launchCatching { + if (!hasEgg) { + activity.inventoryRepository.purchaseItem("eggs", thisEgg.key, 1) + } + if (!hasPotion) { + activity.inventoryRepository.purchaseItem( + "hatchingPotions", + thisPotion.key, + 1 + ) + } + activity.userRepository.retrieveUser(true, forced = true) + hatchPet(thisPotion, thisEgg) } - if (!hasPotion) { - activity.inventoryRepository.purchaseItem("hatchingPotions", thisPotion.key, 1) - } - activity.userRepository.retrieveUser(true, forced = true) - hatchPet(thisPotion, thisEgg) - } } } @@ -158,22 +160,20 @@ class PetSuggestHatchDialog(context: Context) : HabiticaAlertDialog(context) { DataBindingUtils.loadImage(context, imageName) { val resources = context.resources ?: return@loadImage val drawable = if (hasMount) it else BitmapDrawable(resources, it.toBitmap().extractAlpha()) - MainScope().launchCatching { + lifecycleScope.launchCatching { binding.petView.bitmap = drawable.toBitmap() } } } private fun hatchPet(potion: HatchingPotion, egg: Egg) { - (getActivity() as? BaseActivity)?.let { - it.lifecycleScope.launchCatching { - hatchPetUseCase.callInteractor( - HatchPetUseCase.RequestValues( - potion, egg, - it - ) + longLivingScope.launchCatching { + hatchPetUseCase.callInteractor( + HatchPetUseCase.RequestValues( + potion, egg, + context ) - } + ) } } diff --git a/Habitica/src/release/java/com/habitrpg/android/habitica/HabiticaApplication.java b/Habitica/src/release/java/com/habitrpg/android/habitica/HabiticaApplication.java index afc43c2c9..bbdcec9f7 100644 --- a/Habitica/src/release/java/com/habitrpg/android/habitica/HabiticaApplication.java +++ b/Habitica/src/release/java/com/habitrpg/android/habitica/HabiticaApplication.java @@ -1,7 +1,5 @@ package com.habitrpg.android.habitica; -import com.habitrpg.android.habitica.components.AppComponent; -import com.habitrpg.android.habitica.components.DaggerAppComponent; import com.habitrpg.android.habitica.modules.AppModule; public class HabiticaApplication extends HabiticaBaseApplication {