From 0f894082a5f2a5ed650832ed19a7cb6006245a29 Mon Sep 17 00:00:00 2001 From: Dheshan Mohandass Date: Tue, 11 Apr 2023 01:15:40 -0400 Subject: [PATCH 1/4] Update README.md (cherry picked from commit 849d650a0ed63567658d338ba4482719df619ebb) --- .../botforge/chat/ui/components/README.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/com/mohandass/botforge/chat/ui/components/README.md b/app/src/main/java/com/mohandass/botforge/chat/ui/components/README.md index f2eee81..9c1c4f1 100644 --- a/app/src/main/java/com/mohandass/botforge/chat/ui/components/README.md +++ b/app/src/main/java/com/mohandass/botforge/chat/ui/components/README.md @@ -20,9 +20,9 @@ code { background-color: dark-grey; color: white; } - - - + + + MessageEntry: Display's Message, along with Metadata, if present. @@ -50,9 +50,9 @@ code { background-color: dark-grey; color: white; } - - - + + + DefaultHeader: Shows AvatarBar, with App branding. @@ -65,4 +65,4 @@ code { background-color: dark-grey; color: white; } Components Used: RoundedIconFromString, Expandable Text - \ No newline at end of file + From b8ceb37db8c12abf5358a95e8f80f444ad434354 Mon Sep 17 00:00:00 2001 From: Dheshan Mohandass Date: Tue, 11 Apr 2023 01:18:14 -0400 Subject: [PATCH 2/4] Update README.md (cherry picked from commit d56f7faef3e4dcb5acd6fe1379b0db5fb72ea50f) --- .../com/mohandass/botforge/chat/ui/components/README.md | 6 ------ 1 file changed, 6 deletions(-) diff --git a/app/src/main/java/com/mohandass/botforge/chat/ui/components/README.md b/app/src/main/java/com/mohandass/botforge/chat/ui/components/README.md index 9c1c4f1..ad54e9b 100644 --- a/app/src/main/java/com/mohandass/botforge/chat/ui/components/README.md +++ b/app/src/main/java/com/mohandass/botforge/chat/ui/components/README.md @@ -8,9 +8,6 @@ SPDX-License-Identifier: MIT Screenshots: - @@ -38,9 +35,6 @@ code { background-color: dark-grey; color: white; }
MessageEntry
- From 751ab5941491e55018037158904e26df65e1c90c Mon Sep 17 00:00:00 2001 From: Dheshan Mohandass Date: Wed, 12 Apr 2023 12:27:06 -0400 Subject: [PATCH 3/4] feat.: Improve Community Bot discovery - Add Recent Bots section to allow new Bots more exposure - Add Explore Section to feature random Bots --- .../botforge/sync/model/dao/BotDao.kt | 24 ++ .../botforge/sync/service/BotService.kt | 4 + .../service/implementation/BotServiceImpl.kt | 8 + .../botforge/sync/ui/BrowseBotsUi.kt | 289 ++++++++++++------ .../sync/viewmodel/BrowseViewModel.kt | 14 + app/src/main/res/values/strings.xml | 2 + 6 files changed, 243 insertions(+), 98 deletions(-) diff --git a/app/src/main/java/com/mohandass/botforge/sync/model/dao/BotDao.kt b/app/src/main/java/com/mohandass/botforge/sync/model/dao/BotDao.kt index 7d2dd6f..8f88a86 100644 --- a/app/src/main/java/com/mohandass/botforge/sync/model/dao/BotDao.kt +++ b/app/src/main/java/com/mohandass/botforge/sync/model/dao/BotDao.kt @@ -74,6 +74,30 @@ interface BotDao { offset: Int = 0 ): List + @Query( + """ + SELECT * FROM bots + ORDER BY bots.createdAt DESC + LIMIT :limit OFFSET :offset + """ + ) + suspend fun getMostRecentBots( + limit: Int = 15, + offset: Int = 0 + ) + : List + + @Query( + """ + SELECT * FROM bots + ORDER BY RANDOM() + LIMIT :limit + """ + ) + suspend fun getRandomBots( + limit: Int = 15, + ): List + // Delete bot with uuid @Query("DELETE FROM bots WHERE uuid = :uuid") suspend fun deleteBot(uuid: String) diff --git a/app/src/main/java/com/mohandass/botforge/sync/service/BotService.kt b/app/src/main/java/com/mohandass/botforge/sync/service/BotService.kt index d537150..ad0c4bc 100644 --- a/app/src/main/java/com/mohandass/botforge/sync/service/BotService.kt +++ b/app/src/main/java/com/mohandass/botforge/sync/service/BotService.kt @@ -14,6 +14,10 @@ interface BotService { suspend fun getBot(uuid: String): BotE? + suspend fun getMostRecentBots(limit: Int = 15, offset: Int = 0): List + + suspend fun getRandomBots(limit: Int = 15): List + suspend fun searchBots(query: String): List suspend fun getBots( diff --git a/app/src/main/java/com/mohandass/botforge/sync/service/implementation/BotServiceImpl.kt b/app/src/main/java/com/mohandass/botforge/sync/service/implementation/BotServiceImpl.kt index fd198ef..b9d7342 100644 --- a/app/src/main/java/com/mohandass/botforge/sync/service/implementation/BotServiceImpl.kt +++ b/app/src/main/java/com/mohandass/botforge/sync/service/implementation/BotServiceImpl.kt @@ -42,6 +42,14 @@ class BotServiceImpl( return botDao.getBot(uuid) } + override suspend fun getMostRecentBots(limit: Int, offset: Int): List { + return botDao.getMostRecentBots(limit, offset) + } + + override suspend fun getRandomBots(limit: Int): List { + return botDao.getRandomBots(limit) + } + // Get bots that match the query override suspend fun searchBots(query: String): List { return botDao.search("*$query*") diff --git a/app/src/main/java/com/mohandass/botforge/sync/ui/BrowseBotsUi.kt b/app/src/main/java/com/mohandass/botforge/sync/ui/BrowseBotsUi.kt index 3c1fe39..8075394 100644 --- a/app/src/main/java/com/mohandass/botforge/sync/ui/BrowseBotsUi.kt +++ b/app/src/main/java/com/mohandass/botforge/sync/ui/BrowseBotsUi.kt @@ -6,10 +6,9 @@ package com.mohandass.botforge.sync.ui import androidx.activity.compose.BackHandler import androidx.compose.foundation.layout.* +import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.grid.GridCells import androidx.compose.foundation.lazy.grid.LazyHorizontalGrid -import androidx.compose.foundation.rememberScrollState -import androidx.compose.foundation.verticalScroll import androidx.compose.material3.* import androidx.compose.runtime.* import androidx.compose.runtime.livedata.observeAsState @@ -31,9 +30,10 @@ import com.slaviboy.composeunits.adh fun BrowseBotsUi(viewModel: AppViewModel) { val searchText by viewModel.browse.searchQuery val communityBots = viewModel.browse.fetchedBots - val topBots = viewModel.browse.topBots - val scrollState = rememberScrollState() + val topBots = viewModel.browse.topBots + val recentBots = viewModel.browse.recentBots + val randomBots = viewModel.browse.randomBots var isUserGeneratedContentEnabled by remember { mutableStateOf(false) @@ -69,69 +69,160 @@ fun BrowseBotsUi(viewModel: AppViewModel) { .fillMaxSize(), tonalElevation = 0.1.dp, ) { - Column( - modifier = Modifier - .verticalScroll(scrollState) - ) { - Spacer(modifier = Modifier.height(10.dp)) - - Row( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 20.dp), - verticalAlignment = Alignment.CenterVertically - ) { - Icon( - painter = painterResource(id = R.drawable.community), - contentDescription = null, + LazyColumn { + item { + Spacer(modifier = Modifier.height(10.dp)) + + Row( modifier = Modifier - .size(30.dp) + .fillMaxWidth() + .padding(horizontal = 20.dp), + verticalAlignment = Alignment.CenterVertically + ) { + Icon( + painter = painterResource(id = R.drawable.community), + contentDescription = null, + modifier = Modifier + .size(30.dp) + ) + Text( + text = stringResource(id = R.string.community), + modifier = Modifier.padding(10.dp), + style = MaterialTheme.typography.headlineMedium + ) + + Spacer(modifier = Modifier.weight(1f)) + + IconButton(onClick = { + viewModel.browse.syncWithDatabase() + }) { + Icon( + painter = painterResource(id = R.drawable.baseline_cloud_sync_24), + contentDescription = stringResource(id = R.string.sync_cd), + modifier = Modifier + .size(30.dp) + ) + } + } + } + + item { + SearchBar( + searchQuery = searchText, + onClear = { + viewModel.browse.updateSearchQuery("") + }, + label = stringResource(id = R.string.community_search) + ) { + viewModel.browse.updateSearchQuery(it) + } + } + + item { + Text( + text = stringResource(id = R.string.community_browse), + modifier = Modifier.padding(horizontal = 20.dp, vertical = 10.dp), + style = MaterialTheme.typography.headlineSmall ) + Text( - text = stringResource(id = R.string.community), - modifier = Modifier.padding(10.dp), - style = MaterialTheme.typography.headlineMedium + text = stringResource(id = R.string.community_browse_message), + modifier = Modifier.padding(horizontal = 20.dp), + style = MaterialTheme.typography.bodyMedium ) - Spacer(modifier = Modifier.weight(1f)) + Spacer(modifier = Modifier.height(10.dp)) + } - IconButton(onClick = { - viewModel.browse.syncWithDatabase() - }) { - Icon( - painter = painterResource(id = R.drawable.baseline_cloud_sync_24), - contentDescription = stringResource(id = R.string.sync_cd), + item { + if (communityBots.isNotEmpty()) { + LazyHorizontalGrid( + rows = GridCells.Adaptive(minSize = 100.dp), modifier = Modifier - .size(30.dp) - ) + .fillMaxWidth() + .heightIn(max = 0.4.adh), + contentPadding = PaddingValues(horizontal = 5.dp, vertical = 5.dp) + ) { + // use Bot's UUID as key + items( + count = communityBots.size, + key = { communityBots[it].uuid } + ) { idx -> + BotCard( + botE = communityBots[idx], + onClickButton = { + viewModel.browse.makePersona(communityBots[idx]) + }, + onUpVote = { + viewModel.browse.upVote(communityBots[idx].uuid) + }, + onDownVote = { + viewModel.browse.downVote(communityBots[idx].uuid) + }, + onReport = { + viewModel.browse.report(communityBots[idx].uuid) + } + ) + } + } + } else if (searchText.isNotEmpty()) { + NoMatches() } } - SearchBar( - searchQuery = searchText, - onClear = { - viewModel.browse.updateSearchQuery("") - }, - label = stringResource(id = R.string.community_search) - ) { - viewModel.browse.updateSearchQuery(it) + item { + Text( + text = stringResource(id = R.string.community_most_popular), + modifier = Modifier.padding(horizontal = 20.dp, vertical = 10.dp), + style = MaterialTheme.typography.headlineSmall + ) + + Spacer(modifier = Modifier.height(10.dp)) } - Text( - text = stringResource(id = R.string.community_browse), - modifier = Modifier.padding(horizontal = 20.dp, vertical = 10.dp), - style = MaterialTheme.typography.headlineSmall - ) + item { + LazyHorizontalGrid( + rows = GridCells.Adaptive(minSize = 100.dp), + modifier = Modifier + .fillMaxWidth() + .heightIn(max = 0.4.adh), + contentPadding = PaddingValues(horizontal = 5.dp, vertical = 5.dp) + ) { + // use Bot's UUID as key + items( + count = topBots.size, + key = { topBots[it].uuid } + ) { idx -> + BotCard( + botE = topBots[idx], + onClickButton = { + viewModel.browse.makePersona(topBots[idx]) + }, + onUpVote = { + viewModel.browse.upVote(topBots[idx].uuid) + }, + onDownVote = { + viewModel.browse.downVote(topBots[idx].uuid) + }, + onReport = { + viewModel.browse.report(topBots[idx].uuid) + } + ) + } + } + } - Text( - text = stringResource(id = R.string.community_browse_message), - modifier = Modifier.padding(horizontal = 20.dp), - style = MaterialTheme.typography.bodyMedium - ) + item { + Text( + text = stringResource(id = R.string.community_explore), + modifier = Modifier.padding(horizontal = 20.dp, vertical = 10.dp), + style = MaterialTheme.typography.headlineSmall + ) - Spacer(modifier = Modifier.height(10.dp)) + Spacer(modifier = Modifier.height(10.dp)) + } - if (communityBots.isNotEmpty()) { + item { LazyHorizontalGrid( rows = GridCells.Adaptive(minSize = 100.dp), modifier = Modifier @@ -139,71 +230,73 @@ fun BrowseBotsUi(viewModel: AppViewModel) { .heightIn(max = 0.4.adh), contentPadding = PaddingValues(horizontal = 5.dp, vertical = 5.dp) ) { - // use Bot's UUID as key items( - count = communityBots.size, - key = { communityBots[it].uuid } + count = randomBots.size, + key = { randomBots[it].uuid } ) { idx -> BotCard( - botE = communityBots[idx], + botE = randomBots[idx], onClickButton = { - viewModel.browse.makePersona(communityBots[idx]) + viewModel.browse.makePersona(randomBots[idx]) }, onUpVote = { - viewModel.browse.upVote(communityBots[idx].uuid) + viewModel.browse.upVote(randomBots[idx].uuid) }, onDownVote = { - viewModel.browse.downVote(communityBots[idx].uuid) + viewModel.browse.downVote(randomBots[idx].uuid) }, onReport = { - viewModel.browse.report(communityBots[idx].uuid) + viewModel.browse.report(randomBots[idx].uuid) } ) } } - } else if (searchText.isNotEmpty()) { - NoMatches() } - Text( - text = stringResource(id = R.string.community_most_popular), - modifier = Modifier.padding(horizontal = 20.dp, vertical = 10.dp), - style = MaterialTheme.typography.headlineSmall - ) - - Spacer(modifier = Modifier.height(10.dp)) - - LazyHorizontalGrid( - rows = GridCells.Adaptive(minSize = 100.dp), - modifier = Modifier - .fillMaxWidth() - .heightIn(max = 0.4.adh), - contentPadding = PaddingValues(horizontal = 5.dp, vertical = 5.dp) - ) { - // use Bot's UUID as key - items( - count = topBots.size, - key = { topBots[it].uuid } - ) { idx -> - BotCard( - botE = topBots[idx], - onClickButton = { - viewModel.browse.makePersona(topBots[idx]) - }, - onUpVote = { - viewModel.browse.upVote(topBots[idx].uuid) - }, - onDownVote = { - viewModel.browse.downVote(topBots[idx].uuid) - }, - onReport = { - viewModel.browse.report(topBots[idx].uuid) - } - ) + item { + Text( + text = stringResource(id = R.string.community_most_recent), + modifier = Modifier.padding(horizontal = 20.dp, vertical = 10.dp), + style = MaterialTheme.typography.headlineSmall + ) + + Spacer(modifier = Modifier.height(10.dp)) + } + + item { + LazyHorizontalGrid( + rows = GridCells.Adaptive(minSize = 100.dp), + modifier = Modifier + .fillMaxWidth() + .heightIn(max = 0.4.adh), + contentPadding = PaddingValues(horizontal = 5.dp, vertical = 5.dp) + ) { + items( + count = recentBots.size, + key = { recentBots[it].uuid } + ) { idx -> + BotCard( + botE = recentBots[idx], + onClickButton = { + viewModel.browse.makePersona(recentBots[idx]) + }, + onUpVote = { + viewModel.browse.upVote(recentBots[idx].uuid) + }, + onDownVote = { + viewModel.browse.downVote(recentBots[idx].uuid) + }, + onReport = { + viewModel.browse.report(recentBots[idx].uuid) + } + ) + } } } - Spacer(modifier = Modifier.height(0.1.adh)) + item { + Spacer(modifier = Modifier.height(0.1.adh)) + } } } } diff --git a/app/src/main/java/com/mohandass/botforge/sync/viewmodel/BrowseViewModel.kt b/app/src/main/java/com/mohandass/botforge/sync/viewmodel/BrowseViewModel.kt index f26c215..d0703bb 100644 --- a/app/src/main/java/com/mohandass/botforge/sync/viewmodel/BrowseViewModel.kt +++ b/app/src/main/java/com/mohandass/botforge/sync/viewmodel/BrowseViewModel.kt @@ -47,6 +47,12 @@ class BrowseViewModel @Inject constructor( private val _topBots = mutableStateListOf() val topBots = _topBots + private val _recentBots = mutableStateListOf() + val recentBots = _recentBots + + private val _randomBots = mutableStateListOf() + val randomBots = _randomBots + // Populate the top bots list with the bots from the Community fun fetchBots() { logger.logVerbose(TAG, "fetchBots()") @@ -54,6 +60,14 @@ class BrowseViewModel @Inject constructor( _topBots.clear() _topBots.addAll(botService.getBots()) } + viewModelScope.launch { + _recentBots.clear() + _recentBots.addAll(botService.getMostRecentBots()) + } + viewModelScope.launch { + _randomBots.clear() + _randomBots.addAll(botService.getRandomBots()) + } } init { diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 7726274..0bd0b5c 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -234,6 +234,8 @@ Browse Bots Browse community bots and templates. Most Popular Bots + Explore + Most Recent Sync No bots matching your search found. From d168df7d25776ffa7cd88c1c2f17b5ccd391fa0d Mon Sep 17 00:00:00 2001 From: Dheshan Mohandass Date: Wed, 12 Apr 2023 12:39:56 -0400 Subject: [PATCH 4/4] release: Build #23 --- app/build.gradle | 6 +++--- build.gradle | 2 ++ 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index f24cdd3..147bbf9 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -43,8 +43,8 @@ android { applicationId "com.mohandass.botforge" minSdk 28 targetSdk 33 - versionCode 22 - versionName "1.2.2" + versionCode 23 + versionName "1.2.3" vectorDrawables { useSupportLibrary true @@ -140,7 +140,7 @@ dependencies { implementation 'com.google.firebase:firebase-perf-ktx' implementation 'com.google.firebase:firebase-appcheck-ktx' - implementation 'com.google.android.gms:play-services-auth:20.4.1' + implementation "com.google.android.gms:play-services-auth:$play_services_auth_version" // gson implementation "com.google.code.gson:gson:$gson_version" diff --git a/build.gradle b/build.gradle index 4eb0f2e..a1ab5d7 100644 --- a/build.gradle +++ b/build.gradle @@ -19,6 +19,8 @@ buildscript { accompanist_version = "0.29.2-rc" compose_markdown_version = "0.3.1" coil_version = "2.2.2" + + play_services_auth_version = "20.5.0" } repositories { google()
DefaultHeader