Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/main' into 534-do-not-allow-th…
Browse files Browse the repository at this point in the history
…e-creation-of-new-phrases-with-recent-ceategory

allows PR tests to run on this forked branch
  • Loading branch information
cinadia committed Jun 4, 2024
2 parents badab68 + 97e88ce commit edd8304
Show file tree
Hide file tree
Showing 15 changed files with 346 additions and 170 deletions.
67 changes: 11 additions & 56 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,65 +25,20 @@ jobs:
- name: Run Unit Tests
run: ./gradlew testDebug

- name: Upload test results
if: always()
uses: actions/upload-artifact@v3
with:
name: test-results
path: app/build/reports/

- name: Assemble
env:
VERSION_CODE: ${{ github.run_number }}
run: ./gradlew assembleDebug assembleDebugAndroidTest

- name: Decode Firebase Service Account JSON
run: echo ${{ secrets.FIREBASE_SERVICE_ACCOUNT_BASE_64 }} | base64 -d > service_account.json

- name: 'Run Device Tests on Firebase Test Lab'
run: |
gcloud auth login --cred-file=service_account.json
gcloud config set project vocable-fcb07
gcloud firebase test android run \
--app app/build/outputs/apk/debug/app-debug.apk \
--test app/build/outputs/apk/androidTest/debug/app-debug-androidTest.apk \
--device version=34,orientation=portrait,model=MediumPhone.arm,locale=en_US \
--test-runner-class com.willowtree.vocable.utility.VocableTestRunner
- name: Decode Keystore
if: github.event_name != 'pull_request'
env:
ENCODED_RELEASE_KEYSTORE: ${{ secrets.ENCODED_RELEASE_KEYSTORE }}
run: echo $ENCODED_RELEASE_KEYSTORE | base64 -d > keystore

- name: Build & Assemble Release APK
if: github.event_name != 'pull_request'
env:
VERSION_CODE: ${{ github.run_number }}
RELEASE_KEY_ALIAS: ${{ secrets.RELEASE_KEY_ALIAS }}
RELEASE_KEY_PASSWORD: ${{ secrets.RELEASE_KEY_PASSWORD }}
run: |
./gradlew assembleRelease
- name: Install Firebase CLI
if: github.event_name != 'pull_request'
run: npm install -g firebase-tools

- name: Decode Firebase Service Account JSON
if: github.event_name != 'pull_request'
run: echo ${{ secrets.FIREBASE_SERVICE_ACCOUNT_BASE_64 }} | base64 -d > service_account.json

- name: Deploy to Firebase
if: github.event_name != 'pull_request'
env:
GOOGLE_APPLICATION_CREDENTIALS: service_account.json
run: firebase appdistribution:distribute app/build/outputs/apk/release/app-release.apk --app ${{ secrets.FIREBASE_APP_ID }} --groups "internal"

- name: Upload to Play Store
if: github.event_name != 'pull_request'
uses: r0adkll/upload-google-play@v1
- uses: actions/upload-artifact@v4
with:
serviceAccountJsonPlainText: ${{ secrets.PLAY_STORE_CREDENTIALS }}
packageName: com.willowtree.vocable
releaseFiles: app/build/outputs/apk/release/app-release.apk
track: alpha
name: apk
path: |
app/build/outputs/apk/debug/app-debug.apk
app/build/outputs/apk/androidTest/debug/app-debug-androidTest.apk
pre-release-upload:
needs: build
if: github.event_name != 'pull_request'
uses: ./.github/workflows/pre-release-upload.yml
secrets: inherit
42 changes: 42 additions & 0 deletions .github/workflows/device-tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
name: Run Device Tests
# Run device tests using Firebase Test Lab
#
# This action is separated so that it can run on PRs coming from forks, without
# giving those forks access to our repository secrets, which are necessary to run against Firebase.
# There is also additional configuration so this workflow can be reused in our main workflow and block
# deployments on UI test results.

on:
workflow_run:
workflows: ["Build & Test Project"]
branches-ignore: [main]
types:
- completed
workflow_call:

jobs:
device-tests:
runs-on: ubuntu-20.04
if: ${{ github.event.workflow_run.conclusion == 'success' || github.event_name != 'workflow_run' }}
steps:
- uses: haya14busa/action-workflow_run-status@v1
if: ${{ github.event_name == 'workflow_run' }}
- name: Set RUN_ID
run: echo "RUN_ID=${{ github.event_name == 'workflow_run' && github.event.workflow_run.id || github.run_id }}" >> $GITHUB_ENV
- uses: actions/download-artifact@v4
with:
run-id: ${{ env.RUN_ID }}
github-token: ${{ secrets.GITHUB_TOKEN }}

- name: Decode Firebase Service Account JSON
run: echo ${{ secrets.FIREBASE_SERVICE_ACCOUNT_BASE_64 }} | base64 -d > service_account.json

- name: 'Run Device Tests on Firebase Test Lab'
run: |
gcloud auth login --cred-file=service_account.json
gcloud config set project vocable-fcb07
gcloud firebase test android run \
--app apk/debug/app-debug.apk \
--test apk/androidTest/debug/app-debug-androidTest.apk \
--device version=34,orientation=portrait,model=MediumPhone.arm,locale=en_US \
--test-runner-class com.willowtree.vocable.utility.VocableTestRunner
55 changes: 55 additions & 0 deletions .github/workflows/pre-release-upload.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
name: Pre-Release Upload

on:
workflow_call:

jobs:
device-tests:
uses: ./.github/workflows/device-tests.yml
secrets: inherit

pre-release-upload:
needs: device-tests
runs-on: ubuntu-20.04
steps:
- name: Checkout code
uses: actions/checkout@v3

- name: Set Up JDK 17
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'temurin'
cache: gradle

- name: Decode Keystore
env:
ENCODED_RELEASE_KEYSTORE: ${{ secrets.ENCODED_RELEASE_KEYSTORE }}
run: echo $ENCODED_RELEASE_KEYSTORE | base64 -d > keystore

- name: Build & Assemble Release APK
env:
VERSION_CODE: ${{ github.run_number }}
RELEASE_KEY_ALIAS: ${{ secrets.RELEASE_KEY_ALIAS }}
RELEASE_KEY_PASSWORD: ${{ secrets.RELEASE_KEY_PASSWORD }}
run: |
./gradlew assembleRelease
- name: Install Firebase CLI
run: npm install -g firebase-tools

- name: Decode Firebase Service Account JSON
run: echo ${{ secrets.FIREBASE_SERVICE_ACCOUNT_BASE_64 }} | base64 -d > service_account.json

- name: Deploy to Firebase
env:
GOOGLE_APPLICATION_CREDENTIALS: service_account.json
run: firebase appdistribution:distribute app/build/outputs/apk/release/app-release.apk --app ${{ secrets.FIREBASE_APP_ID }} --groups "internal"

- name: Upload to Play Store
uses: r0adkll/upload-google-play@v1
with:
serviceAccountJsonPlainText: ${{ secrets.PLAY_STORE_CREDENTIALS }}
packageName: com.willowtree.vocable
releaseFiles: app/build/outputs/apk/release/app-release.apk
track: alpha
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ Use a list of common phrases provided by speech language pathologists, or create
Type with your head or your hands.

## Roadmap
For the current progress on features, please visit the [project board](https://github.com/willowtreeapps/vocable-android/projects/1).
For the current progress on features, please visit the [project board](https://github.com/orgs/willowtreeapps/projects/50/views/1).

For a high-level roadmap, see the [Vocable Roadmap](./ROADMAP.md)

Expand Down
2 changes: 2 additions & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ dependencies {
testImplementation 'junit:junit:4.13.2'
testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:$coroutines_version"
testImplementation "androidx.arch.core:core-testing:2.2.0"
testImplementation(libs.turbine)
androidTestImplementation "androidx.room:room-testing:2.2.5"
androidTestImplementation 'androidx.test:runner:1.4.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
Expand All @@ -123,6 +124,7 @@ dependencies {
androidTestImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:$coroutines_version"
androidTestImplementation 'androidx.test:rules:1.4.0'
androidTestImplementation "androidx.arch.core:core-testing:2.2.0"
androidTestImplementation(libs.turbine)

// Testing Navigation
androidTestImplementation "androidx.navigation:navigation-testing:2.3.1"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ class MainScreen {
onView(withText(phrase)).check(matches(isDisplayed()))
}
}

// Taps on the selected phrase
fun tapPhrase(phraseText: String) {
onView(withText(phraseText)).tap()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
package com.willowtree.vocable.tests

import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.rule.GrantPermissionRule
import com.willowtree.vocable.screens.MainScreen
import com.willowtree.vocable.utility.assertTextMatches
import org.junit.Ignore
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,20 @@ class PresetsViewModel(
categoriesUseCase.categories(),
liveSelectedCategoryId
) { categories, selectedId ->
categories.find { it.categoryId == selectedId }
val currentCategory = categories.find { it.categoryId == selectedId }
if (currentCategory?.hidden == true) {
val newSortOrder = (currentCategory.sortOrder + 1)
val newCategory = categories.find { it.sortOrder == newSortOrder}
if (newCategory != null) {
liveSelectedCategoryId.update { newCategory.categoryId }
categories.find { it.sortOrder == newSortOrder}
} else {
liveSelectedCategoryId.update { categories.first().categoryId }
categories.first()
}
} else {
currentCategory
}
}.stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000L), null)
val selectedCategoryLiveData: LiveData<Category?> = selectedCategory.asLiveData()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ import android.os.Bundle
import android.view.View
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import androidx.navigation.fragment.findNavController
import androidx.viewpager2.widget.ViewPager2
import com.willowtree.vocable.BaseFragment
Expand All @@ -13,6 +16,7 @@ import com.willowtree.vocable.R
import com.willowtree.vocable.databinding.FragmentEditCategoriesBinding
import com.willowtree.vocable.presets.Category
import com.willowtree.vocable.utils.VocableFragmentStateAdapter
import kotlinx.coroutines.launch
import org.koin.androidx.viewmodel.ViewModelOwner
import org.koin.androidx.viewmodel.ext.android.viewModel
import kotlin.math.min
Expand Down Expand Up @@ -107,9 +111,13 @@ class EditCategoriesFragment : BaseFragment<FragmentEditCategoriesBinding>() {
}

private fun subscribeToViewModel() {
editCategoriesViewModel.categoryList.observe(viewLifecycleOwner) {
it?.let { categories ->
categoriesAdapter.setItems(categories)
viewLifecycleOwner.lifecycleScope.launch {
viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
editCategoriesViewModel.categoryList.collect {
it.let { categories ->
categoriesAdapter.setItems(categories)
}
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import androidx.navigation.fragment.findNavController
import com.willowtree.vocable.BaseFragment
import com.willowtree.vocable.BindingInflater
Expand All @@ -12,6 +15,7 @@ import com.willowtree.vocable.databinding.CategoryEditButtonBinding
import com.willowtree.vocable.databinding.FragmentEditCategoriesListBinding
import com.willowtree.vocable.presets.Category
import com.willowtree.vocable.utils.locale.LocalizedResourceUtility
import kotlinx.coroutines.launch
import org.koin.android.ext.android.inject
import org.koin.androidx.viewmodel.ViewModelOwner
import org.koin.androidx.viewmodel.ext.android.viewModel
Expand Down Expand Up @@ -101,22 +105,26 @@ class EditCategoriesListFragment : BaseFragment<FragmentEditCategoriesListBindin
}

private fun subscribeToViewModel() {
editCategoriesViewModel.categoryList.observe(viewLifecycleOwner) { list ->
list?.let { overallList ->
val hiddenCategories = overallList.filter { it.hidden }
if (endPosition > overallList.size) {
endPosition = overallList.size - 1
}
if (startPosition <= endPosition) {
overallList.subList(startPosition, endPosition)
.forEachIndexed { index, category ->
bindCategoryEditButton(
editButtonList[index],
category,
startPosition + index,
overallList.size - hiddenCategories.size
)
viewLifecycleOwner.lifecycleScope.launch {
viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
editCategoriesViewModel.categoryList.collect { list ->
list.let { overallList ->
val hiddenCategories = overallList.filter { it.hidden }
if (endPosition > overallList.size) {
endPosition = overallList.size - 1
}
if (startPosition <= endPosition) {
overallList.subList(startPosition, endPosition)
.forEachIndexed { index, category ->
bindCategoryEditButton(
editButtonList[index],
category,
startPosition + index,
overallList.size - hiddenCategories.size
)
}
}
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,18 @@ package com.willowtree.vocable.settings
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.asLiveData
import androidx.lifecycle.viewModelScope
import com.willowtree.vocable.ICategoriesUseCase
import com.willowtree.vocable.presets.Category
import com.willowtree.vocable.room.CategorySortOrder
import com.willowtree.vocable.settings.editcategories.EditCategoriesPage
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch

class EditCategoriesViewModel(
private val categoriesUseCase: ICategoriesUseCase
) : ViewModel() {

val categoryList: LiveData<List<Category>> = categoriesUseCase.categories().asLiveData()

val categoryPages = categoriesUseCase.categories().map { categories ->
val pageSize = 8
categories.chunked(pageSize).map { EditCategoriesPage(it) }
}
val categoryList = categoriesUseCase.categories()

private val liveLastViewedIndex = MutableLiveData<Int>()
val lastViewedIndex: LiveData<Int> = liveLastViewedIndex
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/res/values/dimens.xml
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@
<dimen name="edit_category_pager_margin_bottom">44dp</dimen>
<dimen name="edit_individual_category_padding_start">20dp</dimen>
<dimen name="edit_individual_category_padding_end">0dp</dimen>
<dimen name="edit_individual_category_padding">10dp</dimen>
<dimen name="edit_individual_category_padding">5dp</dimen>
<dimen name="edit_individual_category_margin_top">20dp</dimen>

<!-- Edit Categories List -->
Expand Down
Loading

0 comments on commit edd8304

Please sign in to comment.