Skip to content

Commit

Permalink
Merge pull request #5607 from streetcomplete/compose1
Browse files Browse the repository at this point in the history
First steps in Jetpack Compose (reimplement parts of the user screen)
  • Loading branch information
westnordost committed May 5, 2024
2 parents bd94440 + b085594 commit dbf4d5d
Show file tree
Hide file tree
Showing 87 changed files with 1,618 additions and 2,446 deletions.
19 changes: 18 additions & 1 deletion app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import java.util.Properties
plugins {
id("com.android.application")
kotlin("android")
kotlin("plugin.serialization") version "1.9.22"
kotlin("plugin.serialization") version "1.9.23"
}

android {
Expand Down Expand Up @@ -52,6 +52,7 @@ android {
buildConfigField("boolean", "IS_GOOGLE_PLAY", "false")
}
getByName("debug") {
isMinifyEnabled = false
proguardFiles(getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro")
applicationIdSuffix = ".debug"
buildConfigField("boolean", "IS_GOOGLE_PLAY", "false")
Expand All @@ -65,6 +66,11 @@ android {
buildFeatures {
viewBinding = true
buildConfig = true
compose = true
}

composeOptions {
kotlinCompilerExtensionVersion = "1.5.12"
}

bundle {
Expand Down Expand Up @@ -140,7 +146,18 @@ dependencies {
implementation("androidx.viewpager:viewpager:1.0.0")
implementation("androidx.localbroadcastmanager:localbroadcastmanager:1.1.0")

// Jetpack Compose
val composeBom = platform("androidx.compose:compose-bom:2024.04.01")
implementation(composeBom)
androidTestImplementation(composeBom)
implementation("androidx.compose.material:material")
// Jetpack Compose Previews
implementation("androidx.compose.ui:ui-tooling-preview")
debugImplementation("androidx.compose.ui:ui-tooling")


Check failure on line 158 in app/build.gradle.kts

View workflow job for this annotation

GitHub Actions / Kotlin

Needless blank line(s)
implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.7.0")
implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.7.0")
// photos
implementation("androidx.exifinterface:exifinterface:1.3.7")

Expand Down
3 changes: 0 additions & 3 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,6 @@
<activity
android:name="de.westnordost.streetcomplete.screens.settings.debug.ShowQuestFormsActivity"
android:configChanges="orientation|screenSize|uiMode" />
<activity
android:name="de.westnordost.streetcomplete.screens.settings.debug.ShowLinksActivity"
android:configChanges="orientation|screenSize|uiMode" />
<activity
android:name="de.westnordost.streetcomplete.screens.user.UserActivity"
android:screenOrientation="portrait"
Expand Down
5 changes: 0 additions & 5 deletions app/src/main/java/de/westnordost/streetcomplete/Prefs.kt
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,6 @@ object Prefs {
const val ACTIVE_DATES_RANGE = "active_days_range"
const val IS_SYNCHRONIZING_STATISTICS = "is_synchronizing_statistics"

const val LAST_SHOWN_USER_GLOBAL_RANK = "last_shown.user_global_rank"
const val LAST_SHOWN_USER_LOCAL_RANK = "last_shown.user_local_rank"
const val LAST_SHOWN_USER_GLOBAL_RANK_CURRENT_WEEK = "last_shown.user_global_rank_current_week"
const val LAST_SHOWN_USER_LOCAL_RANK_CURRENT_WEEK = "last_shown.user_local_rank_current_week"

enum class Autosync {
ON,
WIFI,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,8 @@ private val typeAliases = listOf(
"ShopsOverlay" to PlacesOverlay::class.simpleName!!,
)

private val links = listOf(
/** this is only public so that it can be previewed in compose */
val links = listOf(

/* ---------------------------------------- Intro ----------------------------------------*/
Link(
Expand Down Expand Up @@ -495,7 +496,8 @@ private val links = listOf(

private val linksById = links.associateBy { it.id }

private val achievements = listOf(
/** this is only public so that it can be previewed in compose */
val achievements = listOf(

Achievement(
"first_edit",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ class AboutFragment : TwoPaneListFragment(), HasTitle {
binding.imageView.setImageResource(with.iconId)
binding.textView.text = with.title
binding.root.setOnClickListener { openUri(with.url) }
TextViewCompat.setTextAppearance(binding.textView, R.style.TextAppearance_Title)
TextViewCompat.setTextAppearance(binding.textView, R.style.TextAppearance_TitleLarge)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
package de.westnordost.streetcomplete.screens.main.messages

import android.os.Bundle
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.appcompat.app.AlertDialog
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.fragment.app.Fragment
import de.westnordost.streetcomplete.R
import de.westnordost.streetcomplete.data.messages.Message
Expand All @@ -10,15 +15,33 @@ import de.westnordost.streetcomplete.data.messages.OsmUnreadMessagesMessage
import de.westnordost.streetcomplete.data.messages.QuestSelectionHintMessage
import de.westnordost.streetcomplete.screens.about.WhatsNewDialog
import de.westnordost.streetcomplete.screens.settings.SettingsActivity
import de.westnordost.streetcomplete.screens.user.achievements.AchievementInfoFragment
import de.westnordost.streetcomplete.screens.user.achievements.AchievementDialog
import de.westnordost.streetcomplete.ui.util.composableContent
import kotlinx.coroutines.flow.MutableStateFlow

/** A fragment that contains any fragments that would show messages.
* Usually, messages are shown as dialogs, however there is currently one exception which
* makes this necessary as a fragment */
class MessagesContainerFragment : Fragment(R.layout.fragment_messages_container) {
class MessagesContainerFragment : Fragment() {

private val shownMessage = MutableStateFlow<Message?>(null)

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?) = composableContent {
val message by shownMessage.collectAsState()

val msg = message
if (msg is NewAchievementMessage) {
AchievementDialog(
msg.achievement,
msg.level,
onDismissRequest = { shownMessage.value = null }
)
}
}

fun showMessage(message: Message) {
val ctx = context ?: return
shownMessage.value = message
when (message) {
is OsmUnreadMessagesMessage -> {
OsmUnreadMessagesFragment
Expand All @@ -30,8 +53,7 @@ class MessagesContainerFragment : Fragment(R.layout.fragment_messages_container)
.show()
}
is NewAchievementMessage -> {
val f: Fragment = childFragmentManager.findFragmentById(R.id.achievement_info_fragment)!!
(f as AchievementInfoFragment).showNew(message.achievement, message.level)
shownMessage.value = message
}
is QuestSelectionHintMessage -> {
AlertDialog.Builder(ctx)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import de.westnordost.streetcomplete.R
import de.westnordost.streetcomplete.databinding.DialogDeleteCacheBinding
import de.westnordost.streetcomplete.screens.HasTitle
import de.westnordost.streetcomplete.screens.TwoPaneListFragment
import de.westnordost.streetcomplete.screens.settings.debug.ShowLinksActivity
import de.westnordost.streetcomplete.screens.settings.debug.ShowQuestFormsActivity
import de.westnordost.streetcomplete.util.ktx.format
import de.westnordost.streetcomplete.util.ktx.observe
Expand Down Expand Up @@ -70,11 +69,6 @@ class SettingsFragment : TwoPaneListFragment(), HasTitle {
startActivity(Intent(context, ShowQuestFormsActivity::class.java))
true
}

findPreference<Preference>("debug.links")?.setOnPreferenceClickListener {
startActivity(Intent(context, ShowLinksActivity::class.java))
true
}
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package de.westnordost.streetcomplete.screens.settings

import de.westnordost.streetcomplete.screens.settings.debug.ShowLinksActivityViewModel
import de.westnordost.streetcomplete.screens.settings.debug.ShowLinksActivityViewModelImpl
import de.westnordost.streetcomplete.screens.settings.debug.ShowQuestFormsViewModel
import de.westnordost.streetcomplete.screens.settings.debug.ShowQuestFormsViewModelImpl
import de.westnordost.streetcomplete.screens.settings.questselection.QuestPresetsViewModel
Expand All @@ -19,5 +17,4 @@ val settingsModule = module {
viewModel<QuestSelectionViewModel> { QuestSelectionViewModelImpl(get(), get(), get(), get(), get(named("CountryBoundariesLazy")), get()) }
viewModel<QuestPresetsViewModel> { QuestPresetsViewModelImpl(get(), get(), get(), get()) }
viewModel<ShowQuestFormsViewModel> { ShowQuestFormsViewModelImpl(get(), get()) }
viewModel<ShowLinksActivityViewModel> { ShowLinksActivityViewModelImpl(get(named("Links"))) }
}

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package de.westnordost.streetcomplete.screens.user

import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import de.westnordost.streetcomplete.ui.theme.hint
import de.westnordost.streetcomplete.ui.theme.titleLarge

@Composable
fun CenteredLargeTitleHint(text: String, modifier: Modifier = Modifier) {
Box(
modifier = modifier.fillMaxSize(),
contentAlignment = Alignment.Center
) {
Text(
text = text,
modifier = Modifier.padding(64.dp),
style = MaterialTheme.typography.titleLarge,
color = MaterialTheme.colors.hint,
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,8 @@ import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import de.westnordost.streetcomplete.R
import de.westnordost.streetcomplete.data.osm.edits.EditType
import de.westnordost.streetcomplete.data.user.achievements.Achievement
import de.westnordost.streetcomplete.screens.FragmentContainerActivity
import de.westnordost.streetcomplete.screens.HasTitle
import de.westnordost.streetcomplete.screens.user.achievements.AchievementInfoFragment
import de.westnordost.streetcomplete.screens.user.achievements.AchievementsFragment
import de.westnordost.streetcomplete.screens.user.login.LoginFragment
import de.westnordost.streetcomplete.screens.user.statistics.CountryInfoFragment
import de.westnordost.streetcomplete.screens.user.statistics.EditStatisticsFragment
Expand All @@ -24,11 +21,10 @@ import org.koin.androidx.viewmodel.ext.android.viewModel
* This activity coordinates quite a number of fragments, which all call back to this one. In order
* of appearance:
* The LoginFragment, the UserFragment (which contains the viewpager with more
* fragments) and the "fake" dialogs AchievementInfoFragment and QuestTypeInfoFragment.
* fragments) and the "fake" dialog QuestTypeInfoFragment.
* */
class UserActivity :
FragmentContainerActivity(R.layout.activity_user),
AchievementsFragment.Listener,
EditStatisticsFragment.Listener {

private val viewModel by viewModel<UserViewModel>()
Expand All @@ -39,9 +35,6 @@ class UserActivity :
private val editTypeDetailsFragment get() =
supportFragmentManager.findFragmentById(R.id.editTypeDetailsFragment) as EditTypeInfoFragment?

private val achievementDetailsFragment get() =
supportFragmentManager.findFragmentById(R.id.achievementDetailsFragment) as AchievementInfoFragment?

private val fragmentLifecycleCallbacks = object : FragmentManager.FragmentLifecycleCallbacks() {
override fun onFragmentStarted(fragmentManager: FragmentManager, fragment: Fragment) {
if (fragment.id == R.id.fragment_container && fragment is HasTitle) {
Expand Down Expand Up @@ -86,12 +79,6 @@ class UserActivity :
}
}

/* ---------------------------- AchievementsFragment.Listener ------------------------------- */

override fun onClickedAchievement(achievement: Achievement, level: Int, achievementBubbleView: View) {
achievementDetailsFragment?.show(achievement, level, achievementBubbleView)
}

/* --------------------------- QuestStatisticsFragment.Listener ----------------------------- */

override fun onClickedEditType(editType: EditType, editCount: Int, questBubbleView: View) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import org.koin.dsl.module

val userScreenModule = module {
factory<ProfileViewModel> { ProfileViewModelImpl(
get(), get(), get(), get(), get(), get(), get(named("AvatarsCacheDirectory")), get()
get(), get(), get(), get(), get(), get(), get(named("AvatarsCacheDirectory"))
) }

factory<LoginViewModel> { LoginViewModelImpl(get(), get(), get(), get()) }
Expand Down

0 comments on commit dbf4d5d

Please sign in to comment.