diff --git a/openfeedback-m2/src/main/java/io/openfeedback/android/m2/OpenFeedbackLayout.kt b/openfeedback-m2/src/main/java/io/openfeedback/android/m2/OpenFeedbackLayout.kt index 20f835c..07822cd 100644 --- a/openfeedback-m2/src/main/java/io/openfeedback/android/m2/OpenFeedbackLayout.kt +++ b/openfeedback-m2/src/main/java/io/openfeedback/android/m2/OpenFeedbackLayout.kt @@ -16,6 +16,9 @@ import io.openfeedback.android.viewmodels.OpenFeedbackViewModel import io.openfeedback.android.viewmodels.models.UISessionFeedback import io.openfeedback.android.viewmodels.models.UIVoteItem +@Deprecated( + message = "Use OpenFeedback component with projectId parameter." +) @Composable fun OpenFeedback( openFeedbackState: OpenFeedbackConfig, @@ -23,9 +26,31 @@ fun OpenFeedback( language: String, modifier: Modifier = Modifier, loading: @Composable () -> Unit = { Loading(modifier = modifier) } +) = OpenFeedback( + config = openFeedbackState, + projectId = openFeedbackState.openFeedbackProjectId, + sessionId = sessionId, + language = language, + modifier = modifier, + loading = loading +) + +@Composable +fun OpenFeedback( + config: OpenFeedbackConfig, + projectId: String, + sessionId: String, + language: String, + modifier: Modifier = Modifier, + loading: @Composable () -> Unit = { Loading(modifier = modifier) } ) { val viewModel: OpenFeedbackViewModel = viewModel( - factory = OpenFeedbackViewModel.Factory.create(openFeedbackState, sessionId, language) + factory = OpenFeedbackViewModel.Factory.create( + openFeedbackConfig = config, + projectId = projectId, + sessionId = sessionId, + language = language + ) ) val uiState = viewModel.uiState.collectAsState() when (uiState.value) { diff --git a/openfeedback-m3/src/main/kotlin/io/openfeedback/android/m3/OpenFeedbackLayout.kt b/openfeedback-m3/src/main/kotlin/io/openfeedback/android/m3/OpenFeedbackLayout.kt index 800bbdd..b649417 100644 --- a/openfeedback-m3/src/main/kotlin/io/openfeedback/android/m3/OpenFeedbackLayout.kt +++ b/openfeedback-m3/src/main/kotlin/io/openfeedback/android/m3/OpenFeedbackLayout.kt @@ -17,6 +17,9 @@ import io.openfeedback.android.viewmodels.OpenFeedbackViewModel import io.openfeedback.android.viewmodels.models.UISessionFeedback import io.openfeedback.android.viewmodels.models.UIVoteItem +@Deprecated( + message = "Use OpenFeedback component with projectId parameter." +) @Composable fun OpenFeedback( openFeedbackState: OpenFeedbackConfig, @@ -24,9 +27,31 @@ fun OpenFeedback( language: String, modifier: Modifier = Modifier, loading: @Composable () -> Unit = { Loading(modifier = modifier) } +) = OpenFeedback( + config = openFeedbackState, + projectId = openFeedbackState.openFeedbackProjectId, + sessionId = sessionId, + language = language, + modifier = modifier, + loading = loading +) + +@Composable +fun OpenFeedback( + config: OpenFeedbackConfig, + projectId: String, + sessionId: String, + language: String, + modifier: Modifier = Modifier, + loading: @Composable () -> Unit = { Loading(modifier = modifier) } ) { val viewModel: OpenFeedbackViewModel = viewModel( - factory = OpenFeedbackViewModel.Factory.create(openFeedbackState, sessionId, language) + factory = OpenFeedbackViewModel.Factory.create( + openFeedbackConfig = config, + projectId = projectId, + sessionId = sessionId, + language = language + ) ) val uiState = viewModel.uiState.collectAsState() when (uiState.value) { diff --git a/openfeedback-viewmodel/src/main/java/io/openfeedback/android/viewmodels/OpenFeedbackUIExtensions.kt b/openfeedback-viewmodel/src/main/java/io/openfeedback/android/viewmodels/OpenFeedbackUIExtensions.kt index a496c04..8af1cf7 100644 --- a/openfeedback-viewmodel/src/main/java/io/openfeedback/android/viewmodels/OpenFeedbackUIExtensions.kt +++ b/openfeedback-viewmodel/src/main/java/io/openfeedback/android/viewmodels/OpenFeedbackUIExtensions.kt @@ -4,9 +4,10 @@ import io.openfeedback.android.OpenFeedbackConfig import io.openfeedback.android.viewmodels.models.UISessionFeedback import kotlinx.coroutines.flow.combine -/** - * A bunch of extensions to get UI models from a openFeedback object - */ +@Deprecated( + message = "Use getUISessionFeedback(projectId: String, sessionId: String, language: String) instead of this one.", + replaceWith = ReplaceWith("getUISessionFeedback(openFeedbackProjectId, sessionId, language)") +) internal suspend fun OpenFeedbackConfig.getUISessionFeedback( sessionId: String, language: String @@ -21,6 +22,24 @@ internal suspend fun OpenFeedbackConfig.getUISessionFeedback( ) } +/** + * A bunch of extensions to get UI models from a openFeedback object + */ +internal suspend fun OpenFeedbackConfig.getUISessionFeedback( + projectId: String, + sessionId: String, + language: String +) = combine( + getProject(projectId), + getUserVotes(projectId, sessionId), + getTotalVotes(projectId, sessionId) +) { project, userVotes, totalVotes -> + return@combine UISessionFeedbackWithColors( + OpenFeedbackModelHelper.toUISessionFeedback(project, userVotes, totalVotes, language), + project.chipColors + ) +} + internal data class UISessionFeedbackWithColors( val session: UISessionFeedback, val colors: List diff --git a/openfeedback-viewmodel/src/main/java/io/openfeedback/android/viewmodels/OpenFeedbackViewModel.kt b/openfeedback-viewmodel/src/main/java/io/openfeedback/android/viewmodels/OpenFeedbackViewModel.kt index 8a6b1b4..0b4f0cd 100644 --- a/openfeedback-viewmodel/src/main/java/io/openfeedback/android/viewmodels/OpenFeedbackViewModel.kt +++ b/openfeedback-viewmodel/src/main/java/io/openfeedback/android/viewmodels/OpenFeedbackViewModel.kt @@ -18,6 +18,7 @@ sealed class OpenFeedbackUiState { class OpenFeedbackViewModel( private val openFeedbackConfig: OpenFeedbackConfig, + private val projectId: String, private val sessionId: String, private val language: String ) : ViewModel() { @@ -26,7 +27,7 @@ class OpenFeedbackViewModel( init { viewModelScope.launch { - openFeedbackConfig.getUISessionFeedback(sessionId, language).collect { + openFeedbackConfig.getUISessionFeedback(projectId, sessionId, language).collect { val oldSession = if (uiState.value is OpenFeedbackUiState.Success) (uiState.value as OpenFeedbackUiState.Success).session else null @@ -43,6 +44,7 @@ class OpenFeedbackViewModel( fun vote(voteItem: UIVoteItem) = viewModelScope.launch { openFeedbackConfig.setVote( + projectId = projectId, talkId = sessionId, voteItemId = voteItem.id, status = if (!voteItem.votedByUser) VoteStatus.Active else VoteStatus.Deleted @@ -50,10 +52,34 @@ class OpenFeedbackViewModel( } object Factory { + @Deprecated( + message = "Use create(openFeedbackConfig: OpenFeedbackConfig, projectId: String, sessionId: String, language: String) instead of this one.", + replaceWith = ReplaceWith("create(config, openFeedbackProjectId, sessionId, language)") + ) fun create(openFeedbackConfig: OpenFeedbackConfig, sessionId: String, language: String) = object : ViewModelProvider.Factory { override fun create(modelClass: Class): T = - OpenFeedbackViewModel(openFeedbackConfig, sessionId, language) as T + OpenFeedbackViewModel( + openFeedbackConfig = openFeedbackConfig, + projectId = openFeedbackConfig.openFeedbackProjectId, + sessionId = sessionId, + language = language + ) as T } + + fun create( + openFeedbackConfig: OpenFeedbackConfig, + projectId: String, + sessionId: String, + language: String + ) = object : ViewModelProvider.Factory { + override fun create(modelClass: Class): T = + OpenFeedbackViewModel( + openFeedbackConfig = openFeedbackConfig, + projectId = projectId, + sessionId = sessionId, + language = language + ) as T + } } } diff --git a/openfeedback/src/main/java/io/openfeedback/android/OpenFeedbackConfig.kt b/openfeedback/src/main/java/io/openfeedback/android/OpenFeedbackConfig.kt index bdcde3d..ead389c 100644 --- a/openfeedback/src/main/java/io/openfeedback/android/OpenFeedbackConfig.kt +++ b/openfeedback/src/main/java/io/openfeedback/android/OpenFeedbackConfig.kt @@ -26,12 +26,11 @@ import java.util.Date class OpenFeedbackConfig( context: Context, firebaseConfig: FirebaseConfig, - val openFeedbackProjectId: String, appName: String = "openfeedback" ) { - val firestore: FirebaseFirestore val auth: FirebaseAuth + var openFeedbackProjectId: String = "" class OptimisticVotes( var lastValue: Map?, @@ -50,6 +49,18 @@ class OpenFeedbackConfig( val databaseUrl: String ) + @Deprecated( + message = "Openfeedback project id should be passed in parameter in functions" + ) + constructor( + context: Context, + firebaseConfig: FirebaseConfig, + openFeedbackProjectId: String, + appName: String = "openfeedback" + ) : this(context, firebaseConfig, appName) { + this.openFeedbackProjectId = openFeedbackProjectId + } + init { val options = FirebaseOptions.Builder() .setProjectId(firebaseConfig.projectId) @@ -83,19 +94,31 @@ class OpenFeedbackConfig( auth.currentUser } - suspend fun getProject(): Flow = flow { + @Deprecated( + message = "Use getProject(projectId: String) instead of this one.", + replaceWith = ReplaceWith("getProject(openFeedbackProjectId)") + ) + suspend fun getProject(): Flow = getProject(openFeedbackProjectId) + + suspend fun getProject(projectId: String): Flow = flow { firestore.collection("projects") - .document(openFeedbackProjectId) + .document(projectId) .toFlow() .collect { documentSnapshot -> documentSnapshot.toObject(Project::class.java)?.let { emit(it) } } } - fun getUserVotes(sessionId: String) = flow { + @Deprecated( + message = "Use getUserVotes(projectId: String, sessionId: String) instead of this one.", + replaceWith = ReplaceWith("getUserVotes(openFeedbackProjectId, sessionId)") + ) + fun getUserVotes(sessionId: String) = getUserVotes(openFeedbackProjectId, sessionId) + + fun getUserVotes(projectId: String, sessionId: String) = flow { val user = getFirebaseUser() if (user != null) { - firestore.collection("projects/$openFeedbackProjectId/userVotes") + firestore.collection("projects/$projectId/userVotes") .whereEqualTo("userId", user.uid) .toFlow() .collect { querySnapshot -> @@ -107,13 +130,20 @@ class OpenFeedbackConfig( } } - fun getTotalVotes(sessionId: String): Flow> { + @Deprecated( + message = "Use getTotalVotes(projectId: String, sessionId: String) instead of this one.", + replaceWith = ReplaceWith("getTotalVotes(openFeedbackProjectId, sessionId)") + ) + fun getTotalVotes(sessionId: String): Flow> = + getTotalVotes(openFeedbackProjectId, sessionId) + + fun getTotalVotes(projectId: String, sessionId: String): Flow> { val optimisticVotes = optimisticVotes.getOrPut(sessionId) { OptimisticVotes(null, BroadcastChannel(Channel.CONFLATED)) } val channel = Channel>(Channel.CONFLATED) - val registration = firestore.collection("projects/$openFeedbackProjectId/sessionVotes") + val registration = firestore.collection("projects/$projectId/sessionVotes") .document(sessionId) .addSnapshotListener { documentSnapshot, firebaseFirestoreException -> val totalVotes = documentSnapshot!!.data as? Map @@ -139,10 +169,17 @@ class OpenFeedbackConfig( return flowOf(flow1, flow2).flattenMerge() } + @Deprecated( + message = "Use setVote(projectId: String, talkId: String, voteItemId: String, status: VoteStatus) instead of this one.", + replaceWith = ReplaceWith("setVote(openFeedbackProjectId, talkId, voteItemId, status)") + ) suspend fun setVote(talkId: String, voteItemId: String, status: VoteStatus) = + setVote(openFeedbackProjectId, talkId, voteItemId, status) + + suspend fun setVote(projectId: String, talkId: String, voteItemId: String, status: VoteStatus) = withFirebaseUser { firebaseUser -> val collectionReference = - firestore.collection("projects/$openFeedbackProjectId/userVotes") + firestore.collection("projects/$projectId/userVotes") val optimisticVotes = optimisticVotes.getOrPut(talkId) { OptimisticVotes(null, BroadcastChannel(Channel.CONFLATED)) @@ -178,7 +215,7 @@ class OpenFeedbackConfig( mapOf( "id" to documentReference.id, "createdAt" to Date(), - "projectId" to openFeedbackProjectId, + "projectId" to projectId, "status" to status.value, "talkId" to talkId, "updatedAt" to Date(), diff --git a/sample-app/src/main/java/io/openfeedback/android/sample/MainActivity.kt b/sample-app/src/main/java/io/openfeedback/android/sample/MainActivity.kt index 939820b..f2b4d45 100644 --- a/sample-app/src/main/java/io/openfeedback/android/sample/MainActivity.kt +++ b/sample-app/src/main/java/io/openfeedback/android/sample/MainActivity.kt @@ -32,9 +32,9 @@ class MainActivity : AppCompatActivity() { @OptIn(ExperimentalMaterial3Api::class) override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) + val projectId = "mMHR63ARZQpPidFQISyc" val config = OpenFeedbackConfig( context = this, - openFeedbackProjectId = "mMHR63ARZQpPidFQISyc", firebaseConfig = OpenFeedbackConfig.FirebaseConfig( projectId = "openfeedback-b7ab9", applicationId = "1:765209934800:android:a6bb09f3deabc2277297d5", @@ -60,7 +60,8 @@ class MainActivity : AppCompatActivity() { when (designSystem) { DesignSystem.M2 -> Scaffold { OpenFeedback( - openFeedbackState = config, + config = config, + projectId = projectId, sessionId = "173222", language = "en", modifier = Modifier @@ -70,7 +71,8 @@ class MainActivity : AppCompatActivity() { } DesignSystem.M3 -> androidx.compose.material3.Scaffold { io.openfeedback.android.m3.OpenFeedback( - openFeedbackState = config, + config = config, + projectId = projectId, sessionId = "173222", language = "en", modifier = Modifier