├── .editorconfig ├── .github ├── CONTRIBUTING.md ├── ISSUE_TEMPLATE │ ├── Bug_report.md │ └── Feature_request.md ├── PULL_REQUEST_TEMPLATE.md ├── semantic.yml └── workflows │ ├── build.yml │ └── deploy.yml ├── .gitignore ├── .tool-versions ├── CHANGELOG.md ├── CODEOWNERS ├── LICENSE ├── README.md ├── build.gradle.kts ├── docs ├── guide │ ├── Migration_2.5.x_2.6.x.md │ └── Migration_2.x_3.x.md └── img │ ├── banner.png │ ├── codex │ ├── categories_hits.gif │ ├── multiple_index.gif │ ├── query_suggestions.gif │ ├── query_suggestions_categories.gif │ ├── query_suggestions_hits.gif │ ├── query_suggestions_recent.gif │ └── voice_search.gif │ ├── examples │ ├── android.png │ ├── androidtv.png │ └── wearos.png │ ├── guide │ ├── declarative_ui.gif │ ├── imperative_ui.gif │ ├── suggestions.gif │ └── voice_search.gif │ └── showcase │ ├── showcase-compose.gif │ └── showcase-view.gif ├── examples ├── README.md ├── android │ ├── README.md │ ├── build.gradle │ └── src │ │ └── main │ │ ├── AndroidManifest.xml │ │ ├── kotlin │ │ └── com │ │ │ └── algolia │ │ │ └── instantsearch │ │ │ └── examples │ │ │ └── android │ │ │ ├── App.kt │ │ │ ├── Theme.kt │ │ │ ├── codex │ │ │ ├── categorieshits │ │ │ │ ├── MainActivity.kt │ │ │ │ ├── MainViewModel.kt │ │ │ │ ├── Product.kt │ │ │ │ ├── README.md │ │ │ │ └── SearchScreen.kt │ │ │ ├── multipleindex │ │ │ │ ├── Actor.kt │ │ │ │ ├── MainActivity.kt │ │ │ │ ├── MainViewModel.kt │ │ │ │ ├── Movie.kt │ │ │ │ ├── README.md │ │ │ │ └── SearchScreen.kt │ │ │ ├── multisearch │ │ │ │ ├── Actor.kt │ │ │ │ ├── ActorAdapter.kt │ │ │ │ ├── MainActivity.kt │ │ │ │ ├── MainViewModel.kt │ │ │ │ ├── Movie.kt │ │ │ │ ├── MovieAdapter.kt │ │ │ │ └── README.md │ │ │ ├── suggestions │ │ │ │ ├── categories │ │ │ │ │ ├── MainActivity.kt │ │ │ │ │ ├── MainViewModel.kt │ │ │ │ │ ├── README.md │ │ │ │ │ ├── SearchScreen.kt │ │ │ │ │ └── Suggestion.kt │ │ │ │ ├── hits │ │ │ │ │ ├── MainActivity.kt │ │ │ │ │ ├── MainViewModel.kt │ │ │ │ │ ├── Product.kt │ │ │ │ │ ├── README.md │ │ │ │ │ ├── SearchScreen.kt │ │ │ │ │ └── Suggestion.kt │ │ │ │ ├── query │ │ │ │ │ ├── MainActivity.kt │ │ │ │ │ ├── MainViewModel.kt │ │ │ │ │ ├── README.md │ │ │ │ │ ├── SearchScreen.kt │ │ │ │ │ └── Suggestion.kt │ │ │ │ └── recent │ │ │ │ │ ├── MainActivity.kt │ │ │ │ │ ├── MainViewModel.kt │ │ │ │ │ ├── README.md │ │ │ │ │ ├── SearchScreen.kt │ │ │ │ │ └── Suggestion.kt │ │ │ └── voice │ │ │ │ ├── MainActivity.kt │ │ │ │ ├── MainViewModel.kt │ │ │ │ ├── Product.kt │ │ │ │ ├── README.md │ │ │ │ └── SearchScreen.kt │ │ │ ├── directory │ │ │ ├── Directory.kt │ │ │ ├── DirectoryActivity.kt │ │ │ ├── DirectoryAdapter.kt │ │ │ └── DirectoryItem.kt │ │ │ ├── guides │ │ │ ├── compose │ │ │ │ ├── ComposeActivity.kt │ │ │ │ ├── MainViewModel.kt │ │ │ │ ├── README.md │ │ │ │ ├── SearchScreen.kt │ │ │ │ └── theme │ │ │ │ │ ├── Color.kt │ │ │ │ │ ├── Shape.kt │ │ │ │ │ ├── Theme.kt │ │ │ │ │ └── Type.kt │ │ │ ├── extension │ │ │ │ ├── RecyclerView.kt │ │ │ │ └── SearchView.kt │ │ │ ├── gettingstarted │ │ │ │ ├── FacetFragment.kt │ │ │ │ ├── GettingStartedGuide.kt │ │ │ │ ├── MyFacetListViewHolder.kt │ │ │ │ ├── MyViewModel.kt │ │ │ │ ├── ProductAdapter.kt │ │ │ │ ├── ProductFragment.kt │ │ │ │ └── README.md │ │ │ ├── insights │ │ │ │ ├── InsightsActivity.kt │ │ │ │ ├── ListItemAdapter.kt │ │ │ │ └── README.md │ │ │ └── model │ │ │ │ ├── Product.kt │ │ │ │ └── Suggestion.kt │ │ │ └── showcase │ │ │ ├── androidview │ │ │ ├── Demo.kt │ │ │ ├── README.md │ │ │ ├── customdata │ │ │ │ ├── Banner.kt │ │ │ │ └── QueryRuleCustomDataShowcase.kt │ │ │ ├── directory │ │ │ │ ├── AndroidViewDirectoryShowcase.kt │ │ │ │ └── Directory.kt │ │ │ ├── filter │ │ │ │ ├── clear │ │ │ │ │ └── FilterClearShowcase.kt │ │ │ │ ├── current │ │ │ │ │ └── ShowcaseFilterCurrent.kt │ │ │ │ ├── facet │ │ │ │ │ ├── FacetListPersistentShowcase.kt │ │ │ │ │ ├── FacetListSearchShowcase.kt │ │ │ │ │ ├── FacetListShowcase.kt │ │ │ │ │ ├── FacetListViewHolderImpl.kt │ │ │ │ │ └── dynamic │ │ │ │ │ │ ├── DynamicFacetShowcase.kt │ │ │ │ │ │ └── ViewHolderFactory.kt │ │ │ │ ├── list │ │ │ │ │ ├── FilterListAdapter.kt │ │ │ │ │ ├── FilterListFacetShowcase.kt │ │ │ │ │ ├── FilterListNumericShowcase.kt │ │ │ │ │ ├── FilterListTagShowcase.kt │ │ │ │ │ └── FilterListViewHolder.kt │ │ │ │ ├── map │ │ │ │ │ └── FilterMapShowcase.kt │ │ │ │ ├── numeric │ │ │ │ │ └── comparison │ │ │ │ │ │ ├── FilterComparisonShowcase.kt │ │ │ │ │ │ ├── FilterPriceView.kt │ │ │ │ │ │ └── FilterYearView.kt │ │ │ │ ├── range │ │ │ │ │ ├── BoundsTextView.kt │ │ │ │ │ ├── FilterRangeShowcase.kt │ │ │ │ │ ├── RangeSliderView.kt │ │ │ │ │ └── RangeTextView.kt │ │ │ │ ├── rating │ │ │ │ │ ├── RatingBarView.kt │ │ │ │ │ ├── RatingShowcase.kt │ │ │ │ │ └── RatingTextView.kt │ │ │ │ └── toggle │ │ │ │ │ └── FilterToggleShowcase.kt │ │ │ ├── hierarchical │ │ │ │ ├── HierarchicalAdapter.kt │ │ │ │ ├── HierarchicalShowcase.kt │ │ │ │ └── HierarchicalViewHolder.kt │ │ │ ├── highlighting │ │ │ │ ├── HighlightingAdapter.kt │ │ │ │ ├── HighlightingShowcase.kt │ │ │ │ └── HighlightingViewHolder.kt │ │ │ ├── list │ │ │ │ ├── actor │ │ │ │ │ ├── Actor.kt │ │ │ │ │ ├── ActorAdapterNested.kt │ │ │ │ │ ├── ActorViewHolder.kt │ │ │ │ │ └── ActorViewHolderSmall.kt │ │ │ │ ├── header │ │ │ │ │ └── HeaderViewHolder.kt │ │ │ │ ├── movie │ │ │ │ │ ├── Movie.kt │ │ │ │ │ ├── MovieAdapter.kt │ │ │ │ │ ├── MovieAdapterNested.kt │ │ │ │ │ ├── MovieAdapterPaged.kt │ │ │ │ │ ├── MovieDiffUtil.kt │ │ │ │ │ ├── MovieViewHolder.kt │ │ │ │ │ └── MovieViewHolderNested.kt │ │ │ │ ├── paging │ │ │ │ │ ├── PagingMultiSearchAdapter.kt │ │ │ │ │ ├── PagingMultipleIndexItem.kt │ │ │ │ │ ├── PagingMultipleIndexShowcase.kt │ │ │ │ │ ├── PagingMultipleIndexViewHolder.kt │ │ │ │ │ └── PagingSingleIndexShowcase.kt │ │ │ │ ├── product │ │ │ │ │ ├── Product.kt │ │ │ │ │ └── ProductAdapter.kt │ │ │ │ └── suggestion │ │ │ │ │ └── Suggestion.kt │ │ │ ├── loading │ │ │ │ └── LoadingShowcase.kt │ │ │ ├── relateditems │ │ │ │ └── RelatedItemsShowcase.kt │ │ │ ├── search │ │ │ │ ├── SearchAsYouTypeShowcase.kt │ │ │ │ └── SearchOnSubmitShowcase.kt │ │ │ ├── sortby │ │ │ │ └── SortByShowcase.kt │ │ │ └── stats │ │ │ │ └── StatsShowcase.kt │ │ │ ├── compose │ │ │ ├── Demo.kt │ │ │ ├── README.md │ │ │ ├── customdata │ │ │ │ └── QueryRuleCustomDataShowcase.kt │ │ │ ├── directory │ │ │ │ ├── ComposeDirectoryShowcase.kt │ │ │ │ ├── Directory.kt │ │ │ │ └── DirectoryScreen.kt │ │ │ ├── filter │ │ │ │ ├── clear │ │ │ │ │ └── FilterClearShowcase.kt │ │ │ │ ├── current │ │ │ │ │ └── FilterCurrentShowcase.kt │ │ │ │ ├── facet │ │ │ │ │ ├── DynamicFacetShowcase.kt │ │ │ │ │ ├── FacetListPersistentShowcase.kt │ │ │ │ │ ├── FacetListSearchShowcase.kt │ │ │ │ │ └── FacetListShowcase.kt │ │ │ │ ├── list │ │ │ │ │ ├── FilterListFacetShowcase.kt │ │ │ │ │ ├── FilterListNumericShowcase.kt │ │ │ │ │ ├── FilterListScreen.kt │ │ │ │ │ └── FilterListTagShowcase.kt │ │ │ │ ├── map │ │ │ │ │ └── FilterMapShowcase.kt │ │ │ │ ├── numeric │ │ │ │ │ └── comparison │ │ │ │ │ │ └── FilterComparisonShowcase.kt │ │ │ │ ├── range │ │ │ │ │ ├── FilterRangeShowcase.kt │ │ │ │ │ └── RangeUI.kt │ │ │ │ ├── rating │ │ │ │ │ └── RatingShowcase.kt │ │ │ │ └── toggle │ │ │ │ │ └── FilterToggleShowcase.kt │ │ │ ├── hierarchical │ │ │ │ └── HierarchicalShowcase.kt │ │ │ ├── highlighting │ │ │ │ └── HighlightingShowcase.kt │ │ │ ├── list │ │ │ │ └── paging │ │ │ │ │ ├── PagingMultipleIndexShowcase.kt │ │ │ │ │ └── PagingSingleIndexShowcase.kt │ │ │ ├── loading │ │ │ │ └── LoadingShowcase.kt │ │ │ ├── model │ │ │ │ ├── Actor.kt │ │ │ │ ├── Banner.kt │ │ │ │ ├── Movie.kt │ │ │ │ └── Product.kt │ │ │ ├── relateditems │ │ │ │ └── RelatedItemsShowcase.kt │ │ │ ├── search │ │ │ │ ├── SearchAsYouTypeShowcase.kt │ │ │ │ └── SearchOnSubmitShowcase.kt │ │ │ ├── sortby │ │ │ │ └── SortByShowcase.kt │ │ │ ├── stats │ │ │ │ └── StatsShowcase.kt │ │ │ └── ui │ │ │ │ ├── Color.kt │ │ │ │ ├── Shape.kt │ │ │ │ ├── Theme.kt │ │ │ │ ├── Type.kt │ │ │ │ └── component │ │ │ │ ├── ActorsList.kt │ │ │ │ ├── AutoCompleteTextField.kt │ │ │ │ ├── DropdownTextField.kt │ │ │ │ ├── FacetList.kt │ │ │ │ ├── FilterChips.kt │ │ │ │ ├── FilterList.kt │ │ │ │ ├── HeaderFilter.kt │ │ │ │ ├── HeaderFilterConnector.kt │ │ │ │ ├── HelpDialog.kt │ │ │ │ ├── MoviesList.kt │ │ │ │ ├── ProductList.kt │ │ │ │ ├── RatingBar.kt │ │ │ │ ├── RestoreFab.kt │ │ │ │ ├── SearchBox.kt │ │ │ │ └── TopBar.kt │ │ │ └── shared │ │ │ └── customdata │ │ │ └── TemplateActivity.kt │ │ └── res │ │ ├── drawable-anydpi │ │ └── ic_filter_list.xml │ │ ├── drawable │ │ ├── ic_add.xml │ │ ├── ic_add_shopping_cart.xml │ │ ├── ic_arrow_down.xml │ │ ├── ic_arrow_up.xml │ │ ├── ic_arrow_up_right.xml │ │ ├── ic_check.xml │ │ ├── ic_close_hint.xml │ │ ├── ic_delete.xml │ │ ├── ic_info.xml │ │ ├── ic_microphone_outline.xml │ │ ├── ic_remove.xml │ │ ├── ic_restore.xml │ │ ├── ic_search_hint.xml │ │ ├── query_background.xml │ │ ├── rectangle.xml │ │ └── thumb.xml │ │ ├── layout │ │ ├── activity_directory.xml │ │ ├── activity_getting_started.xml │ │ ├── activity_insights.xml │ │ ├── activity_query_suggestion.xml │ │ ├── autocompletetextfield.xml │ │ ├── filter_chip.xml │ │ ├── fragment_facet.xml │ │ ├── fragment_items.xml │ │ ├── fragment_product.xml │ │ ├── header_filter.xml │ │ ├── header_item.xml │ │ ├── include_list.xml │ │ ├── include_plus_minus.xml │ │ ├── include_search.xml │ │ ├── include_search_info.xml │ │ ├── list_facet_selectable.xml │ │ ├── list_item_actor.xml │ │ ├── list_item_header.xml │ │ ├── list_item_highlighting.xml │ │ ├── list_item_large.xml │ │ ├── list_item_large_buy.xml │ │ ├── list_item_movie.xml │ │ ├── list_item_product.xml │ │ ├── list_item_selectable.xml │ │ ├── list_item_small.xml │ │ ├── list_item_suggestion.xml │ │ ├── list_items.xml │ │ ├── menu_item.xml │ │ ├── showcase_directory.xml │ │ ├── showcase_dynamic_facet_list.xml │ │ ├── showcase_facet_list.xml │ │ ├── showcase_facet_list_persistent.xml │ │ ├── showcase_facet_list_search.xml │ │ ├── showcase_filter_clear.xml │ │ ├── showcase_filter_comparison.xml │ │ ├── showcase_filter_current.xml │ │ ├── showcase_filter_list.xml │ │ ├── showcase_filter_map.xml │ │ ├── showcase_filter_range.xml │ │ ├── showcase_filter_rating.xml │ │ ├── showcase_filter_toggle.xml │ │ ├── showcase_filter_toggle_default.xml │ │ ├── showcase_hierarchical.xml │ │ ├── showcase_highlighting.xml │ │ ├── showcase_loading.xml │ │ ├── showcase_multisearch.xml │ │ ├── showcase_paging.xml │ │ ├── showcase_query_rule_custom_data.xml │ │ ├── showcase_query_rule_custom_data_template.xml │ │ ├── showcase_query_suggestion.xml │ │ ├── showcase_relateditems.xml │ │ ├── showcase_search.xml │ │ ├── showcase_search_autocomplete.xml │ │ ├── showcase_sort_by.xml │ │ └── showcase_stats.xml │ │ ├── mipmap-anydpi-v26 │ │ └── ic_launcher.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ ├── ic_launcher_adaptive_back.png │ │ └── ic_launcher_adaptive_fore.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ ├── ic_launcher_adaptive_back.png │ │ └── ic_launcher_adaptive_fore.png │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ ├── ic_launcher_adaptive_back.png │ │ └── ic_launcher_adaptive_fore.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ ├── ic_launcher_adaptive_back.png │ │ └── ic_launcher_adaptive_fore.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ ├── ic_launcher_adaptive_back.png │ │ └── ic_launcher_adaptive_fore.png │ │ └── values │ │ ├── colors.xml │ │ ├── strings.xml │ │ └── styles.xml ├── androidtv │ ├── README.md │ ├── build.gradle │ └── src │ │ └── main │ │ ├── AndroidManifest.xml │ │ ├── java │ │ └── com │ │ │ └── algolia │ │ │ └── instantsearch │ │ │ └── examples │ │ │ └── androidtv │ │ │ ├── MainActivity.kt │ │ │ ├── SearchScreen.kt │ │ │ ├── Show.kt │ │ │ ├── Suggestion.kt │ │ │ └── ui │ │ │ ├── Color.kt │ │ │ ├── SearchBox.kt │ │ │ └── Theme.kt │ │ └── res │ │ ├── drawable │ │ ├── ic_launcher.png │ │ └── movie.png │ │ ├── layout │ │ ├── activity_details.xml │ │ └── activity_main.xml │ │ ├── mipmap-hdpi │ │ └── ic_launcher.webp │ │ ├── mipmap-mdpi │ │ └── ic_launcher.webp │ │ ├── mipmap-xhdpi │ │ └── ic_launcher.webp │ │ ├── mipmap-xxhdpi │ │ └── ic_launcher.webp │ │ ├── mipmap-xxxhdpi │ │ └── ic_launcher.webp │ │ └── values │ │ ├── strings.xml │ │ └── themes.xml └── wearos │ ├── README.md │ ├── build.gradle │ └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── algolia │ │ └── instantsearch │ │ └── example │ │ └── wearos │ │ ├── MainActivity.kt │ │ ├── Show.kt │ │ ├── ShowAdapter.kt │ │ ├── ShowsActivity.kt │ │ └── internal │ │ ├── CustomScrollingLayoutCallback.kt │ │ └── GrayscaleTransformation.kt │ └── res │ ├── drawable-anydpi │ └── ic_mic.xml │ ├── drawable-hdpi │ └── ic_mic.png │ ├── drawable-mdpi │ └── ic_mic.png │ ├── drawable-xhdpi │ └── ic_mic.png │ ├── drawable-xxhdpi │ └── ic_mic.png │ ├── drawable │ └── logo.png │ ├── layout │ ├── activity_main.xml │ ├── activity_shows.xml │ └── list_item.xml │ ├── mipmap-hdpi │ └── ic_launcher.webp │ ├── mipmap-mdpi │ └── ic_launcher.webp │ ├── mipmap-xhdpi │ └── ic_launcher.webp │ ├── mipmap-xxhdpi │ └── ic_launcher.webp │ ├── mipmap-xxxhdpi │ └── ic_launcher.webp │ └── values │ ├── colors.xml │ ├── dimens.xml │ ├── strings.xml │ └── styles.xml ├── extensions ├── android-loading │ ├── README.md │ ├── build.gradle.kts │ ├── gradle.properties │ └── src │ │ ├── main │ │ └── kotlin │ │ │ └── com │ │ │ └── algolia │ │ │ └── instantsearch │ │ │ └── android │ │ │ └── loading │ │ │ └── LoadingViewSwipeRefreshLayout.kt │ │ └── test │ │ └── kotlin │ │ ├── TestLoadingViewSwipeRefreshLayout.kt │ │ └── documentation │ │ └── DocLoading.kt ├── android-paging3 │ ├── README.md │ ├── build.gradle.kts │ ├── gradle.properties │ └── src │ │ └── main │ │ └── kotlin │ │ └── com │ │ └── algolia │ │ └── instantsearch │ │ └── android │ │ └── paging3 │ │ ├── Paginator.kt │ │ ├── facet │ │ ├── FacetListConnector.kt │ │ └── internal │ │ │ └── FacetListConnectionPager.kt │ │ ├── filterstate │ │ ├── FilterStateConnection.kt │ │ └── internal │ │ │ └── FilterStateConnectionPaginator.kt │ │ ├── internal │ │ ├── SearcherPaginator.kt │ │ └── SearcherPagingSource.kt │ │ ├── searchbox │ │ ├── SearchBoxConnection.kt │ │ └── internal │ │ │ └── SearchBoxConnectionPaginator.kt │ │ └── sortby │ │ ├── SortByConnection.kt │ │ └── internal │ │ └── SortByConnectionPaginator.kt └── coroutines-extensions │ ├── README.md │ ├── build.gradle.kts │ ├── gradle.properties │ └── src │ ├── commonMain │ └── kotlin │ │ └── com │ │ └── algolia │ │ └── instantsearch │ │ └── coroutines │ │ └── Subscription.kt │ └── commonTest │ └── kotlin │ └── TestSubscription.kt ├── gradle.properties ├── gradle ├── libs.versions.toml └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── instantsearch-compose ├── build.gradle.kts ├── gradle.properties └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── algolia │ │ │ └── instantsearch │ │ │ └── compose │ │ │ ├── customdata │ │ │ ├── QueryRuleCustomDataState.kt │ │ │ └── internal │ │ │ │ └── QueryRuleCustomDataStateImpl.kt │ │ │ ├── filter │ │ │ ├── clear │ │ │ │ ├── FilterClear.kt │ │ │ │ └── internal │ │ │ │ │ └── FilterClearImpl.kt │ │ │ ├── current │ │ │ │ ├── FilterCurrentState.kt │ │ │ │ └── internal │ │ │ │ │ └── FilterCurrentStateImpl.kt │ │ │ ├── facet │ │ │ │ ├── FacetListState.kt │ │ │ │ ├── dynamic │ │ │ │ │ ├── DynamicFacetListState.kt │ │ │ │ │ └── internal │ │ │ │ │ │ └── DynamicFacetListStateImpl.kt │ │ │ │ └── internal │ │ │ │ │ └── FacetListStateImpl.kt │ │ │ ├── list │ │ │ │ ├── FilterListState.kt │ │ │ │ └── internal │ │ │ │ │ └── FilterListStateImpl.kt │ │ │ ├── map │ │ │ │ ├── FilterMapState.kt │ │ │ │ └── internal │ │ │ │ │ └── FilterMapStateImpl.kt │ │ │ └── toggle │ │ │ │ ├── FilterToggleState.kt │ │ │ │ └── internal │ │ │ │ └── FilterToggleStateImpl.kt │ │ │ ├── hierarchical │ │ │ ├── HierarchicalState.kt │ │ │ └── internal │ │ │ │ └── HierarchicalStateImpl.kt │ │ │ ├── highlighting │ │ │ └── HighlightedString.kt │ │ │ ├── hits │ │ │ ├── HitsState.kt │ │ │ └── internal │ │ │ │ └── HitsStateImpl.kt │ │ │ ├── internal │ │ │ └── Telemetry.kt │ │ │ ├── item │ │ │ ├── StatsState.kt │ │ │ └── internal │ │ │ │ └── StatsStateImpl.kt │ │ │ ├── loading │ │ │ ├── LoadingState.kt │ │ │ └── internal │ │ │ │ └── LoadingStateImpl.kt │ │ │ ├── number │ │ │ ├── NumberState.kt │ │ │ ├── internal │ │ │ │ └── NumberStateImpl.kt │ │ │ ├── range │ │ │ │ ├── NumberRangeState.kt │ │ │ │ └── internal │ │ │ │ │ └── NumberRangeStateImpl.kt │ │ │ └── relevantsort │ │ │ │ ├── RelevantSortState.kt │ │ │ │ └── internal │ │ │ │ └── RelevantSortStateImpl.kt │ │ │ ├── searchbox │ │ │ ├── SearchBox.kt │ │ │ ├── SearchBoxState.kt │ │ │ └── internal │ │ │ │ ├── SearchBoxComponents.kt │ │ │ │ └── SearchBoxStateImpl.kt │ │ │ ├── selectable │ │ │ ├── SelectableItemState.kt │ │ │ ├── internal │ │ │ │ └── SelectableItemStateImpl.kt │ │ │ └── list │ │ │ │ ├── SelectableListState.kt │ │ │ │ └── internal │ │ │ │ └── SelectableListStateImpl.kt │ │ │ └── sortby │ │ │ ├── SortByState.kt │ │ │ └── internal │ │ │ └── SortByStateImpl.kt │ └── res │ │ └── values │ │ └── strings.xml │ └── test │ └── kotlin │ └── com │ └── algolia │ └── instantsearch │ └── compose │ ├── customdata │ └── QueryRuleCustomDataStateTest.kt │ ├── filter │ ├── DynamicFacetListStateTest.kt │ ├── FacetListStateTest.kt │ ├── FilterClearTest.kt │ ├── FilterCurrentStateTest.kt │ ├── FilterMapStateTest.kt │ └── FilterToggleStateTest.kt │ ├── hierarchical │ └── HierarchicalStateTest.kt │ ├── hits │ └── HitsStateTest.kt │ ├── item │ └── StatsTest.kt │ ├── loading │ └── LoadingStateTest.kt │ ├── number │ ├── NumberRangeStateTest.kt │ └── RelevantSortStateTest.kt │ ├── searchbox │ └── SearchBoxStateTest.kt │ ├── selectable │ ├── SelectableItemStateTest.kt │ └── SelectableListStateTest.kt │ ├── sortby │ └── SortByStateTest.kt │ └── telemetry │ └── TestTelemetry.kt ├── instantsearch-core ├── build.gradle.kts ├── gradle.properties └── src │ ├── commonMain │ └── kotlin │ │ └── com │ │ └── algolia │ │ └── instantsearch │ │ └── core │ │ ├── Callback.kt │ │ ├── InstantSearch.kt │ │ ├── Presenter.kt │ │ ├── connection │ │ ├── AbstractConnection.kt │ │ ├── Connection.kt │ │ └── ConnectionHandler.kt │ │ ├── highlighting │ │ ├── HighlightTags.kt │ │ ├── HighlightToken.kt │ │ ├── HighlightTokenizer.kt │ │ └── HighlightedString.kt │ │ ├── hits │ │ ├── HitsConnection.kt │ │ ├── HitsView.kt │ │ └── internal │ │ │ └── HitsConnectionView.kt │ │ ├── internal │ │ ├── Collections.kt │ │ ├── Exception.kt │ │ └── Telemetry.kt │ │ ├── loading │ │ ├── LoadingConnection.kt │ │ ├── LoadingView.kt │ │ ├── LoadingViewModel.kt │ │ └── internal │ │ │ └── LoadingConnectionView.kt │ │ ├── map │ │ └── MapViewModel.kt │ │ ├── number │ │ ├── Computation.kt │ │ ├── DefaultNumberPresenter.kt │ │ ├── NumberConnection.kt │ │ ├── NumberPresenter.kt │ │ ├── NumberView.kt │ │ ├── NumberViewModel.kt │ │ ├── internal │ │ │ └── NumberConnectionView.kt │ │ └── range │ │ │ ├── NumberRangeConnection.kt │ │ │ ├── NumberRangeView.kt │ │ │ ├── NumberRangeViewModel.kt │ │ │ ├── Range.kt │ │ │ └── internal │ │ │ ├── Extensions.kt │ │ │ └── NumberRangeConnectionView.kt │ │ ├── relevantsort │ │ ├── RelevantSortConnection.kt │ │ ├── RelevantSortConnector.kt │ │ ├── RelevantSortPresenter.kt │ │ ├── RelevantSortPriority.kt │ │ ├── RelevantSortView.kt │ │ ├── RelevantSortViewModel.kt │ │ └── internal │ │ │ └── RelevantSortConnectionView.kt │ │ ├── searchbox │ │ ├── SearchBoxConnection.kt │ │ ├── SearchBoxView.kt │ │ ├── SearchBoxViewModel.kt │ │ └── internal │ │ │ └── SearchBoxConnectionView.kt │ │ ├── searcher │ │ ├── Constants.kt │ │ ├── Debouncer.kt │ │ ├── Searcher.kt │ │ ├── SearcherConnection.kt │ │ ├── Sequencer.kt │ │ └── internal │ │ │ └── SearcherConnectionView.kt │ │ ├── selectable │ │ ├── SelectableItemConnection.kt │ │ ├── SelectableItemView.kt │ │ ├── SelectableItemViewModel.kt │ │ ├── internal │ │ │ └── SelectableItemConnectionView.kt │ │ ├── list │ │ │ ├── SelectableItem.kt │ │ │ ├── SelectableListConnection.kt │ │ │ ├── SelectableListView.kt │ │ │ ├── SelectableListViewModel.kt │ │ │ ├── SelectionMode.kt │ │ │ └── internal │ │ │ │ └── SelectableListConnectionView.kt │ │ └── map │ │ │ ├── SelectableMapConnection.kt │ │ │ ├── SelectableMapView.kt │ │ │ ├── SelectableMapViewModel.kt │ │ │ └── internal │ │ │ └── SelectableMapConnectionView.kt │ │ ├── subscription │ │ ├── Subscription.kt │ │ ├── SubscriptionEvent.kt │ │ ├── SubscriptionMerge.kt │ │ ├── SubscriptionValue.kt │ │ └── internal │ │ │ └── SubscriptionOnce.kt │ │ └── tree │ │ ├── Extensions.kt │ │ ├── Node.kt │ │ ├── Tree.kt │ │ ├── TreeConnection.kt │ │ ├── TreePresenter.kt │ │ ├── TreeView.kt │ │ ├── TreeViewModel.kt │ │ └── internal │ │ └── TreeConnectionView.kt │ ├── commonTest │ └── kotlin │ │ ├── Test.kt │ │ ├── connection │ │ └── TestConnection.kt │ │ ├── highlighting │ │ └── TestHighlightTokenizer.kt │ │ ├── loading │ │ └── TestLoadingConnectView.kt │ │ ├── map │ │ └── TestMapViewModel.kt │ │ ├── number │ │ ├── TestComputation.kt │ │ ├── TestNumberConnectView.kt │ │ ├── TestNumberPresenter.kt │ │ ├── TestNumberViewModel.kt │ │ └── range │ │ │ ├── TestNumberRangeConnectView.kt │ │ │ └── TestNumberRangeViewModel.kt │ │ ├── relevantsort │ │ ├── TestRelevantSortConnectView.kt │ │ └── TestRelevantSortViewModel.kt │ │ ├── searchbox │ │ ├── TestSearchBoxConnectView.kt │ │ └── TestSearchBoxViewModel.kt │ │ ├── searcher │ │ ├── TestDebouncer.kt │ │ └── TestSequencer.kt │ │ ├── selectable │ │ ├── TestFilterToggleConnectView.kt │ │ ├── TestSelectableItemViewModel.kt │ │ ├── list │ │ │ ├── TestSelectableListConnectView.kt │ │ │ └── TestSelectableListViewModel.kt │ │ └── map │ │ │ ├── TestSelectableMapConnectView.kt │ │ │ └── TestSelectableMapViewModel.kt │ │ ├── subscription │ │ ├── TestSubscription.kt │ │ ├── TestSubscriptionEvent.kt │ │ └── TestSubscriptionValue.kt │ │ └── tree │ │ ├── TestHierarchicalNode.kt │ │ ├── TestTreeConnectView.kt │ │ └── TestTreePresenter.kt │ └── jvmMain │ └── kotlin │ └── com │ └── algolia │ └── instantsearch │ └── core │ └── internal │ └── Collections.kt ├── instantsearch-insights ├── README.md ├── build.gradle.kts ├── gradle.properties └── src │ ├── androidMain │ ├── AndroidManifest.xml │ └── kotlin │ │ └── com │ │ └── algolia │ │ └── instantsearch │ │ └── insights │ │ ├── Insights.kt │ │ └── internal │ │ ├── InsightsController.kt │ │ ├── data │ │ ├── local │ │ │ └── InsightsPrefsRepository.kt │ │ └── settings │ │ │ └── InsightsEventSettings.kt │ │ ├── extension │ │ ├── Platform.kt │ │ ├── SharedPreferencesDelegate.kt │ │ ├── Time.kt │ │ └── UUID.kt │ │ ├── logging │ │ └── InsightsLogger.kt │ │ └── worker │ │ ├── InsightsWorkManager.kt │ │ └── InsightsWorker.kt │ ├── androidUnitTest │ └── kotlin │ │ └── com │ │ └── algolia │ │ └── instantsearch │ │ └── insights │ │ ├── AndroidTestDatabaseSharedPreferences.kt │ │ ├── InsightsAndroidTest.kt │ │ ├── InsightsTest.kt │ │ ├── MockDistantRepository.kt │ │ ├── MockLocalRepository.kt │ │ ├── TestInsightsEventUploader.kt │ │ └── util │ │ └── WorkerManager.kt │ ├── commonMain │ └── kotlin │ │ └── com │ │ └── algolia │ │ └── instantsearch │ │ └── insights │ │ ├── FilterTrackable.kt │ │ ├── HitsAfterSearchTrackable.kt │ │ ├── Insights.kt │ │ ├── exception │ │ └── InsightsException.kt │ │ └── internal │ │ ├── InsightsController.kt │ │ ├── InsightsMap.kt │ │ ├── cache │ │ ├── InsightsCache.kt │ │ └── InsightsEventCache.kt │ │ ├── data │ │ ├── distant │ │ │ ├── InsightsDistantRepository.kt │ │ │ └── InsightsHttpRepository.kt │ │ ├── local │ │ │ ├── InsightsLocalRepository.kt │ │ │ ├── mapper │ │ │ │ ├── FilterFacetMapper.kt │ │ │ │ ├── InsightsEventDOMapper.kt │ │ │ │ ├── InsightsEventsMapper.kt │ │ │ │ └── Mapper.kt │ │ │ └── model │ │ │ │ ├── FilterFacetDO.kt │ │ │ │ └── InsightsEventDO.kt │ │ └── settings │ │ │ └── InsightsSettings.kt │ │ ├── event │ │ └── EventResponse.kt │ │ ├── extension │ │ ├── Insights.kt │ │ ├── InsightsEvent.kt │ │ ├── Json.kt │ │ ├── Map.kt │ │ ├── Time.kt │ │ └── UUID.kt │ │ ├── logging │ │ └── InsightsLogger.kt │ │ ├── uploader │ │ ├── InsightsEventUploader.kt │ │ └── InsightsUploader.kt │ │ └── worker │ │ └── InsightsManager.kt │ └── jvmMain │ └── kotlin │ └── com │ └── algolia │ └── instantsearch │ └── insights │ └── internal │ ├── extension │ ├── Time.kt │ └── UUID.kt │ └── logging │ └── InsightsLogger.kt ├── instantsearch-utils ├── build.gradle.kts ├── gradle.properties └── src │ ├── androidMain │ └── kotlin │ │ └── com │ │ └── algolia │ │ └── instantsearch │ │ └── platform │ │ └── Env.kt │ ├── commonJvm │ └── kotlin │ │ └── com │ │ └── algolia │ │ └── instantsearch │ │ ├── encode │ │ └── Gzip.kt │ │ └── util │ │ └── uuid.kt │ ├── commonMain │ ├── kotlin │ │ └── com │ │ │ └── algolia │ │ │ └── instantsearch │ │ │ ├── Annotations.kt │ │ │ ├── encode │ │ │ └── Gzip.kt │ │ │ ├── platform │ │ │ └── Env.kt │ │ │ └── util │ │ │ ├── agent.kt │ │ │ └── uuid.kt │ └── templates │ │ └── BuildConfig.kt │ └── jvmMain │ └── kotlin │ └── com │ └── algolia │ └── instantsearch │ └── platform │ └── Env.kt ├── instantsearch ├── build.gradle.kts ├── gradle.properties └── src │ ├── androidMain │ └── kotlin │ │ └── com │ │ └── algolia │ │ └── instantsearch │ │ ├── android │ │ ├── ViewGroup.kt │ │ ├── filter │ │ │ ├── clear │ │ │ │ └── DefaultFilterClearView.kt │ │ │ ├── current │ │ │ │ └── DefaultFilterCurrentView.kt │ │ │ ├── facet │ │ │ │ ├── FacetListAdapter.kt │ │ │ │ ├── FacetListViewHolder.kt │ │ │ │ └── dynamic │ │ │ │ │ ├── DynamicFacetListAdapter.kt │ │ │ │ │ ├── DynamicFacetListViewHolder.kt │ │ │ │ │ └── DynamicFacetModel.kt │ │ │ ├── map │ │ │ │ └── FilterMapViewRadioGroup.kt │ │ │ └── toggle │ │ │ │ └── FilterToggleViewCompoundButton.kt │ │ ├── highlighting │ │ │ └── Extensions.kt │ │ ├── hits │ │ │ ├── HitsArrayAdapter.kt │ │ │ ├── HitsViewConnection.kt │ │ │ └── internal │ │ │ │ └── HitsArrayAdapterConnection.kt │ │ ├── internal │ │ │ └── Telemetry.kt │ │ ├── item │ │ │ ├── StatsTextView.kt │ │ │ └── StatsTextViewSpanned.kt │ │ ├── list │ │ │ └── Extensions.kt │ │ ├── searchbox │ │ │ ├── DefaultSearchBoxView.kt │ │ │ ├── SearchBoxAutoCompleteTextView.kt │ │ │ ├── SearchBoxViewAppCompat.kt │ │ │ └── SearchBoxViewEditText.kt │ │ ├── sortby │ │ │ ├── SortByViewAutocomplete.kt │ │ │ └── SortByViewSpinner.kt │ │ └── stats │ │ │ ├── StatsTextView.kt │ │ │ └── StatsTextViewSpanned.kt │ │ ├── extension │ │ └── Console.kt │ │ └── searcher │ │ └── internal │ │ └── Actual.kt │ ├── androidUnitTest │ └── kotlin │ │ ├── MainCoroutineRule.kt │ │ ├── customdata │ │ └── TestQueryRuleCustomData.kt │ │ ├── documentation │ │ ├── guide │ │ │ └── GuideAnalyticsTag.kt │ │ └── widget │ │ │ ├── DocClearFilters.kt │ │ │ ├── DocCurrentFilters.kt │ │ │ ├── DocFacetList.kt │ │ │ ├── DocFilterComparison.kt │ │ │ ├── DocFilterList.kt │ │ │ ├── DocFilterListFacet.kt │ │ │ ├── DocFilterListNumeric.kt │ │ │ ├── DocFilterListTag.kt │ │ │ ├── DocFilterMap.kt │ │ │ ├── DocFilterState.kt │ │ │ ├── DocFilterToggle.kt │ │ │ ├── DocHierarchicalMenu.kt │ │ │ ├── DocHighlighting.kt │ │ │ ├── DocHits.kt │ │ │ ├── DocNumericRange.kt │ │ │ ├── DocSearchBox.kt │ │ │ ├── DocSortBy.kt │ │ │ └── DocStats.kt │ │ ├── instrumented │ │ ├── InstrumentedTest.kt │ │ ├── filter │ │ │ ├── clear │ │ │ │ └── TestFilterClearViewImpl.kt │ │ │ ├── current │ │ │ │ └── TestFilterCurrentViewImpl.kt │ │ │ ├── map │ │ │ │ └── TestSelectableMapViewRadioGroup.kt │ │ │ └── toggle │ │ │ │ └── TestFilterToggleViewCompoundButton.kt │ │ ├── highlighting │ │ │ └── TestExtensions.kt │ │ ├── searchbox │ │ │ ├── TestSearchBoxAutoCompleteTextView.kt │ │ │ ├── TestSearchBoxEditText.kt │ │ │ └── TestSearchBoxSearchView.kt │ │ ├── sortby │ │ │ └── TestSortByViewSpinner.kt │ │ └── stats │ │ │ ├── TestStatsTextView.kt │ │ │ └── TestStatsTextViewSpanned.kt │ │ ├── relatedItems │ │ └── TestSearcherConnectionRelatedItems.kt │ │ └── tracker │ │ ├── TestFiltersTracker.kt │ │ └── TestHitsTracker.kt │ ├── commonMain │ └── kotlin │ │ └── com │ │ └── algolia │ │ └── instantsearch │ │ ├── attribute │ │ ├── AttributeMatchAndReplace.kt │ │ ├── AttributePresenter.kt │ │ └── DefaultAttributePresenter.kt │ │ ├── customdata │ │ ├── QueryRuleCustomDataConnection.kt │ │ ├── QueryRuleCustomDataConnector.kt │ │ ├── QueryRuleCustomDataPresenter.kt │ │ ├── QueryRuleCustomDataViewModel.kt │ │ └── internal │ │ │ └── QueryRuleCustomDataConnectionSearcherForHits.kt │ │ ├── extension │ │ ├── Console.kt │ │ ├── KSerializer.kt │ │ ├── Telemetry.kt │ │ └── Utils.kt │ │ ├── filter │ │ ├── DefaultFilterPresenter.kt │ │ ├── FilterPresenter.kt │ │ ├── clear │ │ │ ├── ClearMode.kt │ │ │ ├── FilterClearConnection.kt │ │ │ ├── FilterClearConnector.kt │ │ │ ├── FilterClearView.kt │ │ │ ├── FilterClearViewModel.kt │ │ │ └── internal │ │ │ │ ├── FilterClearConnectionFilterState.kt │ │ │ │ └── FilterClearConnectionView.kt │ │ ├── current │ │ │ ├── DefaultFilterCurrentPresenter.kt │ │ │ ├── FilterAndID.kt │ │ │ ├── FilterCurrentConnection.kt │ │ │ ├── FilterCurrentConnector.kt │ │ │ ├── FilterCurrentPresenter.kt │ │ │ ├── FilterCurrentView.kt │ │ │ ├── FilterCurrentViewModel.kt │ │ │ └── internal │ │ │ │ ├── FilterAndID.kt │ │ │ │ ├── FilterCurrentConnectionFilterState.kt │ │ │ │ └── FilterCurrentConnectionView.kt │ │ ├── facet │ │ │ ├── DefaultFacetListPresenter.kt │ │ │ ├── FacetListConnection.kt │ │ │ ├── FacetListConnector.kt │ │ │ ├── FacetListItem.kt │ │ │ ├── FacetListPresenter.kt │ │ │ ├── FacetListView.kt │ │ │ ├── FacetListViewModel.kt │ │ │ ├── FacetSortCriterion.kt │ │ │ ├── dynamic │ │ │ │ ├── AttributedFacets.kt │ │ │ │ ├── DynamicFacetConnection.kt │ │ │ │ ├── DynamicFacetListConnector.kt │ │ │ │ ├── DynamicFacetListView.kt │ │ │ │ ├── DynamicFacetListViewModel.kt │ │ │ │ ├── SelectionsPerAttribute.kt │ │ │ │ └── internal │ │ │ │ │ ├── DynamicFacetListConnectionFilterState.kt │ │ │ │ │ ├── DynamicFacetListConnectionSearcherIndex.kt │ │ │ │ │ ├── DynamicFacetListConnectionView.kt │ │ │ │ │ └── FacetsOrder.kt │ │ │ └── internal │ │ │ │ ├── FacetListConnectionFilterState.kt │ │ │ │ ├── FacetListConnectionSearcher.kt │ │ │ │ ├── FacetListConnectionSearcherForFacets.kt │ │ │ │ └── FacetListConnectionView.kt │ │ ├── list │ │ │ ├── FilterListConnection.kt │ │ │ ├── FilterListConnector.kt │ │ │ ├── FilterListView.kt │ │ │ ├── FilterListViewModel.kt │ │ │ └── internal │ │ │ │ ├── Extensions.kt │ │ │ │ └── FilterListConnectionFilterState.kt │ │ ├── map │ │ │ ├── FilterMapConnection.kt │ │ │ ├── FilterMapConnector.kt │ │ │ ├── FilterMapView.kt │ │ │ ├── FilterMapViewModel.kt │ │ │ └── internal │ │ │ │ └── FilterMapConnectionFilterState.kt │ │ ├── numeric │ │ │ └── comparison │ │ │ │ ├── FilterComparisonComputeBounds.kt │ │ │ │ ├── FilterComparisonConnectFilterState.kt │ │ │ │ ├── FilterComparisonConnector.kt │ │ │ │ └── internal │ │ │ │ └── FilterComparisonConnectionFilterState.kt │ │ ├── range │ │ │ ├── FilterRangeConnection.kt │ │ │ ├── FilterRangeConnectionSearcher.kt │ │ │ ├── FilterRangeConnector.kt │ │ │ ├── FilterRangeViewModel.kt │ │ │ └── internal │ │ │ │ ├── FilterRangeConnectionFilterState.kt │ │ │ │ ├── FilterRangeConnectionSearcherImpl.kt │ │ │ │ └── Mapper.kt │ │ ├── state │ │ │ ├── DSL.kt │ │ │ ├── Extension.kt │ │ │ ├── FilterGroupDescriptor.kt │ │ │ ├── FilterGroupID.kt │ │ │ ├── FilterGroupsDSL.kt │ │ │ ├── FilterOperator.kt │ │ │ ├── FilterState.kt │ │ │ ├── Filters.kt │ │ │ ├── MutableFilters.kt │ │ │ └── internal │ │ │ │ ├── DefaultMutableFilters.kt │ │ │ │ └── FiltersImpl.kt │ │ └── toggle │ │ │ ├── FilterToggleConnection.kt │ │ │ ├── FilterToggleConnector.kt │ │ │ ├── FilterToggleView.kt │ │ │ ├── FilterToggleViewModel.kt │ │ │ └── internal │ │ │ └── FilterToggleConnectionFilterState.kt │ │ ├── hierarchical │ │ ├── DefaultHierarchicalPresenter.kt │ │ ├── Extensions.kt │ │ ├── HierarchicalConnection.kt │ │ ├── HierarchicalConnector.kt │ │ ├── HierarchicalFilter.kt │ │ ├── HierarchicalItem.kt │ │ ├── HierarchicalNode.kt │ │ ├── HierarchicalPath.kt │ │ ├── HierarchicalPresenter.kt │ │ ├── HierarchicalTree.kt │ │ ├── HierarchicalView.kt │ │ ├── HierarchicalViewModel.kt │ │ └── internal │ │ │ ├── Extensions.kt │ │ │ ├── HierarchicalConnectionFilterState.kt │ │ │ └── HierarchicalConnectionSearcher.kt │ │ ├── highlighting │ │ └── Highlightable.kt │ │ ├── index │ │ ├── IndexNamePresenter.kt │ │ └── IndexPresenter.kt │ │ ├── loading │ │ ├── LoadingConnection.kt │ │ ├── LoadingConnector.kt │ │ └── internal │ │ │ └── LoadingConnectionSearcher.kt │ │ ├── relateditems │ │ ├── MatchingPattern.kt │ │ ├── SearcherConnectionRelatedItems.kt │ │ └── internal │ │ │ ├── FilterFacetAndID.kt │ │ │ ├── RelatedItemsConnectionView.kt │ │ │ └── extensions │ │ │ ├── FilterState.kt │ │ │ ├── Indexable.kt │ │ │ ├── MatchingPattern.kt │ │ │ └── Unquote.kt │ │ ├── relevantsort │ │ ├── RelevantSortConnection.kt │ │ ├── RelevantSortConnector.kt │ │ └── internal │ │ │ ├── RelevantSortConnectionSearcherForHits.kt │ │ │ └── RelevantSortConnectorSearcherForHits.kt │ │ ├── searchbox │ │ ├── SearchBoxConnection.kt │ │ ├── SearchBoxConnector.kt │ │ ├── SearchMode.kt │ │ └── internal │ │ │ └── SearchBoxConnectionSearcher.kt │ │ ├── searcher │ │ ├── Extensions.kt │ │ ├── FilterGroupsHolder.kt │ │ ├── IndexNameHolder.kt │ │ ├── SearcherAnswers.kt │ │ ├── SearcherConnection.kt │ │ ├── SearcherForFacets.kt │ │ ├── SearcherForHits.kt │ │ ├── SearcherPlaces.kt │ │ ├── SearcherQuery.kt │ │ ├── SearcherScope.kt │ │ ├── facets │ │ │ ├── FacetsSearcher.kt │ │ │ ├── SearchForFacetQuery.kt │ │ │ └── internal │ │ │ │ ├── DefaultFacetsSearcher.kt │ │ │ │ └── FacetsSearchService.kt │ │ ├── hits │ │ │ ├── HitsSearcher.kt │ │ │ ├── SearchForQuery.kt │ │ │ └── internal │ │ │ │ ├── DefaultHitsSearchService.kt │ │ │ │ └── DefaultHitsSearcher.kt │ │ ├── internal │ │ │ ├── Expected.kt │ │ │ ├── FacetsSearcherConnectionFilterState.kt │ │ │ ├── HitsSearcherConnectionFilterState.kt │ │ │ ├── Loading.kt │ │ │ ├── SearcherAnswersConnectionFilterState.kt │ │ │ ├── SearcherExceptionHandler.kt │ │ │ └── withUserAgent.kt │ │ └── multi │ │ │ ├── MultiSearcher.kt │ │ │ └── internal │ │ │ ├── DefaultMultiSearcher.kt │ │ │ ├── MultiSearchComponent.kt │ │ │ ├── MultiSearchOperation.kt │ │ │ ├── MultiSearchService.kt │ │ │ ├── SearchService.kt │ │ │ └── extension │ │ │ └── ResponseMultiSearch.kt │ │ ├── sortby │ │ ├── SortByConnection.kt │ │ ├── SortByConnector.kt │ │ ├── SortByView.kt │ │ ├── SortByViewModel.kt │ │ └── internal │ │ │ ├── DefaultSortByConnector.kt │ │ │ └── SortByConnectionSearcher.kt │ │ ├── stats │ │ ├── DefaultStatsPresenter.kt │ │ ├── StatsConnection.kt │ │ ├── StatsConnector.kt │ │ ├── StatsPresenter.kt │ │ ├── StatsView.kt │ │ ├── StatsViewModel.kt │ │ └── internal │ │ │ ├── StatsConnectionSearcher.kt │ │ │ └── StatsConnectionView.kt │ │ └── tracker │ │ ├── FilterTracker.kt │ │ ├── HitsTracker.kt │ │ └── internal │ │ ├── FilterDataTracker.kt │ │ ├── HitsDataTracker.kt │ │ ├── InsightsScope.kt │ │ ├── InsightsTracker.kt │ │ ├── QueryIDContainer.kt │ │ ├── SubscriptionJob.kt │ │ └── TrackableSearcher.kt │ ├── commonTest │ └── kotlin │ │ ├── Client.kt │ │ ├── ClientInsights.kt │ │ ├── Extensions.kt │ │ ├── filter │ │ ├── TestFilterPresenterImpl.kt │ │ ├── clear │ │ │ └── TestFilterClearConnectFilterState.kt │ │ ├── current │ │ │ └── TestCurrentFiltersConnectFilterState.kt │ │ ├── facet │ │ │ ├── TestFacetListConnectFilterState.kt │ │ │ ├── TestFacetListConnectSearcher.kt │ │ │ ├── TestFacetListConnectSearcherForFacets.kt │ │ │ ├── TestFacetListConnectView.kt │ │ │ ├── TestFacetListPresenter.kt │ │ │ ├── TestFacetListViewModel.kt │ │ │ └── TestFacetsOrder.kt │ │ ├── list │ │ │ └── TestFilterListConnectFilterState.kt │ │ ├── map │ │ │ └── TestFilterMapConnectFilterState.kt │ │ ├── numeric │ │ │ └── comparison │ │ │ │ ├── TestFilterComparisonComputeBounds.kt │ │ │ │ └── TestFilterComparisonConnectFilterState.kt │ │ ├── range │ │ │ ├── TestFilterRangeConnectFilterState.kt │ │ │ └── TestFilterRangeConnectSearcher.kt │ │ ├── state │ │ │ └── TestFilterState.kt │ │ └── toggle │ │ │ └── TestFilterToggleConnectFilterState.kt │ │ ├── hierarchical │ │ ├── TestExtensions.kt │ │ ├── TestHierarchicalConnectFilterState.kt │ │ └── TestHierarchicalPresenter.kt │ │ ├── highlighting │ │ └── TestHighlightable.kt │ │ ├── index │ │ └── TestIndexPresenter.kt │ │ ├── loading │ │ └── TestLoadingConnectSearcher.kt │ │ ├── relatedItems │ │ ├── Product.kt │ │ ├── TestMachingPattern.kt │ │ └── mockHitsView.kt │ │ ├── searchbox │ │ └── TestSearchBoxConnectSearcher.kt │ │ ├── searcher │ │ ├── Extensions.kt │ │ ├── MockSearcher.kt │ │ ├── TestSearcherAnswers.kt │ │ ├── TestSearcherForFacets.kt │ │ ├── TestSearcherMultipleIndex.kt │ │ └── TestSearcherSingleIndex.kt │ │ ├── sortby │ │ └── TestSortByConnectSearcher.kt │ │ ├── stats │ │ ├── TestStatsConnectSearcher.kt │ │ └── TestStatsPresenter.kt │ │ └── telemetry │ │ └── TestTelemetry.kt │ ├── jvmMain │ └── kotlin │ │ └── com │ │ └── algolia │ │ └── instantsearch │ │ ├── extension │ │ └── Console.kt │ │ └── searcher │ │ └── internal │ │ └── Actual.kt │ └── jvmTest │ └── kotlin │ └── kotlin │ └── MainCoroutineRule.kt ├── renovate.json └── settings.gradle.kts /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | end_of_line = lf 6 | indent_size = 4 7 | indent_style = space 8 | insert_final_newline = true 9 | max_line_length = 120 10 | tab_width = 4 11 | 12 | # noinspection EditorConfigKeyCorrectness 13 | [*.{kt, kts}] 14 | kotlin_imports_layout = idea 15 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/Bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve our libraries 4 | 5 | --- 6 | 7 | 10 | 11 | **Describe the bug 🐛** 12 | A clear and concise description of what the bug is. 13 | 14 | **To Reproduce 🔍** 15 | Steps to reproduce the behavior: 16 | 1. Go to '...' 17 | 2. Click on '....' 18 | 3. Scroll down to '....' 19 | 4. See error 20 | 21 | **Expected behavior 💭** 22 | A clear and concise description of what you expected to happen. 23 | 24 | **Screenshots 🖥** 25 | If applicable, add screenshots to help explain your problem. 26 | 27 | **Environment:** 28 | - OS: [e.g. iOS / windows / mac / android] 29 | - Library Version [e.g. 2.0.0] 30 | 31 | **Additional context** 32 | Add any other context about the problem here. 33 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/Feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | 5 | --- 6 | 7 | 10 | 11 | **Is your feature request related to a problem? Please describe 🙏** 12 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 13 | 14 | **Describe the solution you'd like 🤔** 15 | A clear and concise description of what you want to happen. 16 | 17 | **Describe alternatives you've considered ✨** 18 | A clear and concise description of any alternative solutions or features you've considered. 19 | 20 | **Additional context** 21 | Add any other context or screenshots about the feature request here. 22 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | | Q | A 2 | | ----------------- | ---------- 3 | | Bug fix? | yes/no 4 | | New feature? | yes/no 5 | | BC breaks? | no 6 | | Related Issue | Fix #... 7 | | Need Doc update | yes/no 8 | 9 | 10 | ## Describe your change 11 | 12 | 16 | 17 | ## What problem is this fixing? 18 | 19 | 23 | -------------------------------------------------------------------------------- /.github/semantic.yml: -------------------------------------------------------------------------------- 1 | # Always validate the PR title, and ignore the commits 2 | titleOnly: true 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | .idea 3 | .gradle 4 | .DS_STORE 5 | *.iml 6 | local.properties 7 | *.hprof 8 | .bundle/ 9 | local.settings.gradle.kts 10 | 11 | # fastlane 12 | **/fastlane/report.xml 13 | **/fastlane/Preview.html 14 | **/fastlane/screenshots 15 | **/fastlane/test_output 16 | 17 | # bitrise 18 | .bitrise.yml 19 | bitrise.yml 20 | -------------------------------------------------------------------------------- /.tool-versions: -------------------------------------------------------------------------------- 1 | java temurin-11.0.22+7 2 | -------------------------------------------------------------------------------- /CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @Aallam 2 | -------------------------------------------------------------------------------- /docs/img/banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algolia/instantsearch-android/eaf37a61303a8b9c5688a596e8aeab29dfbba398/docs/img/banner.png -------------------------------------------------------------------------------- /docs/img/codex/categories_hits.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algolia/instantsearch-android/eaf37a61303a8b9c5688a596e8aeab29dfbba398/docs/img/codex/categories_hits.gif -------------------------------------------------------------------------------- /docs/img/codex/multiple_index.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algolia/instantsearch-android/eaf37a61303a8b9c5688a596e8aeab29dfbba398/docs/img/codex/multiple_index.gif -------------------------------------------------------------------------------- /docs/img/codex/query_suggestions.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algolia/instantsearch-android/eaf37a61303a8b9c5688a596e8aeab29dfbba398/docs/img/codex/query_suggestions.gif -------------------------------------------------------------------------------- /docs/img/codex/query_suggestions_categories.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algolia/instantsearch-android/eaf37a61303a8b9c5688a596e8aeab29dfbba398/docs/img/codex/query_suggestions_categories.gif -------------------------------------------------------------------------------- /docs/img/codex/query_suggestions_hits.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algolia/instantsearch-android/eaf37a61303a8b9c5688a596e8aeab29dfbba398/docs/img/codex/query_suggestions_hits.gif -------------------------------------------------------------------------------- /docs/img/codex/query_suggestions_recent.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algolia/instantsearch-android/eaf37a61303a8b9c5688a596e8aeab29dfbba398/docs/img/codex/query_suggestions_recent.gif -------------------------------------------------------------------------------- /docs/img/codex/voice_search.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algolia/instantsearch-android/eaf37a61303a8b9c5688a596e8aeab29dfbba398/docs/img/codex/voice_search.gif -------------------------------------------------------------------------------- /docs/img/examples/android.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algolia/instantsearch-android/eaf37a61303a8b9c5688a596e8aeab29dfbba398/docs/img/examples/android.png -------------------------------------------------------------------------------- /docs/img/examples/androidtv.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algolia/instantsearch-android/eaf37a61303a8b9c5688a596e8aeab29dfbba398/docs/img/examples/androidtv.png -------------------------------------------------------------------------------- /docs/img/examples/wearos.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algolia/instantsearch-android/eaf37a61303a8b9c5688a596e8aeab29dfbba398/docs/img/examples/wearos.png -------------------------------------------------------------------------------- /docs/img/guide/declarative_ui.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algolia/instantsearch-android/eaf37a61303a8b9c5688a596e8aeab29dfbba398/docs/img/guide/declarative_ui.gif -------------------------------------------------------------------------------- /docs/img/guide/imperative_ui.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algolia/instantsearch-android/eaf37a61303a8b9c5688a596e8aeab29dfbba398/docs/img/guide/imperative_ui.gif -------------------------------------------------------------------------------- /docs/img/guide/suggestions.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algolia/instantsearch-android/eaf37a61303a8b9c5688a596e8aeab29dfbba398/docs/img/guide/suggestions.gif -------------------------------------------------------------------------------- /docs/img/guide/voice_search.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algolia/instantsearch-android/eaf37a61303a8b9c5688a596e8aeab29dfbba398/docs/img/guide/voice_search.gif -------------------------------------------------------------------------------- /docs/img/showcase/showcase-compose.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algolia/instantsearch-android/eaf37a61303a8b9c5688a596e8aeab29dfbba398/docs/img/showcase/showcase-compose.gif -------------------------------------------------------------------------------- /docs/img/showcase/showcase-view.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algolia/instantsearch-android/eaf37a61303a8b9c5688a596e8aeab29dfbba398/docs/img/showcase/showcase-view.gif -------------------------------------------------------------------------------- /examples/README.md: -------------------------------------------------------------------------------- 1 | # InstantSearch examples 2 | 3 | * [InstantSearch examples for Android](android) 4 | * [InstantSearch examples for WearOS](wearos) 5 | * [InstantSearch examples for Android TV](androidtv) 6 | -------------------------------------------------------------------------------- /examples/android/src/main/kotlin/com/algolia/instantsearch/examples/android/codex/categorieshits/Product.kt: -------------------------------------------------------------------------------- 1 | package com.algolia.instantsearch.examples.android.codex.categorieshits 2 | 3 | import com.algolia.instantsearch.highlighting.Highlightable 4 | import com.algolia.search.model.Attribute 5 | import com.algolia.search.model.ObjectID 6 | import com.algolia.search.model.indexing.Indexable 7 | import kotlinx.serialization.Serializable 8 | import kotlinx.serialization.json.JsonObject 9 | 10 | @Serializable 11 | data class Product( 12 | val name: String, 13 | val description: String, 14 | val image: String, 15 | override val objectID: ObjectID, 16 | override val _highlightResult: JsonObject? 17 | ) : Indexable, Highlightable { 18 | 19 | val highlightedName 20 | get() = getHighlight(Attribute("name")) 21 | 22 | val highlightedDescription 23 | get() = getHighlight(Attribute("description")) 24 | } 25 | -------------------------------------------------------------------------------- /examples/android/src/main/kotlin/com/algolia/instantsearch/examples/android/codex/categorieshits/README.md: -------------------------------------------------------------------------------- 1 | # Categories & Hits implementation example 2 | 3 | Search experience consisting of two results sections: 4 | - Products categories lists 5 | - Products list 6 | 7 | Demonstrates simultaneous search for hits and facet values. 8 | 9 | 10 | 11 | ## How to run this example 12 | 13 | ### 1. Clone this repository 14 | 15 | ```sh 16 | git clone git@github.com:algolia/instantsearch-android.git 17 | ``` 18 | 19 | ### 2. Build the project 20 | 21 | ```sh 22 | ./gradlew :examples:android:assembleDebug 23 | ``` 24 | 25 | ### 3. Install the app 26 | 27 | ```sh 28 | ./gradlew :examples:android:installDebug 29 | ``` 30 | 31 | ### 4. Launch the example 32 | 33 | The example is under `Code Exchange > Categpries Hits`. 34 | -------------------------------------------------------------------------------- /examples/android/src/main/kotlin/com/algolia/instantsearch/examples/android/codex/multipleindex/Actor.kt: -------------------------------------------------------------------------------- 1 | package com.algolia.instantsearch.examples.android.codex.multipleindex 2 | 3 | import com.algolia.instantsearch.highlighting.Highlightable 4 | import com.algolia.search.model.Attribute 5 | import com.algolia.search.model.ObjectID 6 | import com.algolia.search.model.indexing.Indexable 7 | import kotlinx.serialization.Serializable 8 | import kotlinx.serialization.json.JsonObject 9 | 10 | @Serializable 11 | data class Actor( 12 | val name: String, 13 | override val objectID: ObjectID, 14 | override val _highlightResult: JsonObject? 15 | ) : Indexable, Highlightable { 16 | 17 | val highlightedName 18 | get() = getHighlight(Attribute("name")) 19 | } 20 | -------------------------------------------------------------------------------- /examples/android/src/main/kotlin/com/algolia/instantsearch/examples/android/codex/multipleindex/Movie.kt: -------------------------------------------------------------------------------- 1 | package com.algolia.instantsearch.examples.android.codex.multipleindex 2 | 3 | import com.algolia.instantsearch.highlighting.Highlightable 4 | import com.algolia.search.model.Attribute 5 | import com.algolia.search.model.ObjectID 6 | import com.algolia.search.model.indexing.Indexable 7 | import kotlinx.serialization.Serializable 8 | import kotlinx.serialization.json.JsonObject 9 | 10 | @Serializable 11 | data class Movie( 12 | val title: String, 13 | override val objectID: ObjectID, 14 | override val _highlightResult: JsonObject? 15 | ) : Indexable, Highlightable { 16 | 17 | val highlightedTitle 18 | get() = getHighlight(Attribute("title")) 19 | } 20 | -------------------------------------------------------------------------------- /examples/android/src/main/kotlin/com/algolia/instantsearch/examples/android/codex/multipleindex/README.md: -------------------------------------------------------------------------------- 1 | # Multi-index search implementation example 2 | 3 | Search experience consisting of search in two indices: 4 | - Actors 5 | - Films 6 | 7 | Demonstrates simultaneous search in multiple indices 8 | 9 | 10 | 11 | ## How to run this example 12 | 13 | ### 1. Clone this repository 14 | 15 | ```sh 16 | git clone git@github.com:algolia/instantsearch-android.git 17 | ``` 18 | 19 | ### 2. Build the project 20 | 21 | ```sh 22 | ./gradlew :examples:android:assembleDebug 23 | ``` 24 | 25 | ### 3. Install the app 26 | 27 | ```sh 28 | ./gradlew :examples:android:installDebug 29 | ``` 30 | 31 | ### 4. Launch the example 32 | 33 | The example is under `Code Exchange > Multiple Index`. 34 | -------------------------------------------------------------------------------- /examples/android/src/main/kotlin/com/algolia/instantsearch/examples/android/codex/multisearch/Actor.kt: -------------------------------------------------------------------------------- 1 | package com.algolia.instantsearch.examples.android.codex.multisearch 2 | 3 | import com.algolia.instantsearch.highlighting.Highlightable 4 | import com.algolia.search.model.Attribute 5 | import com.algolia.search.model.ObjectID 6 | import com.algolia.search.model.indexing.Indexable 7 | import kotlinx.serialization.Serializable 8 | import kotlinx.serialization.json.JsonObject 9 | 10 | @Serializable 11 | data class Actor( 12 | val name: String, 13 | override val objectID: ObjectID, 14 | override val _highlightResult: JsonObject? 15 | ) : Indexable, Highlightable { 16 | 17 | val highlightedName 18 | get() = getHighlight(Attribute("name")) 19 | } 20 | -------------------------------------------------------------------------------- /examples/android/src/main/kotlin/com/algolia/instantsearch/examples/android/codex/multisearch/Movie.kt: -------------------------------------------------------------------------------- 1 | package com.algolia.instantsearch.examples.android.codex.multisearch 2 | 3 | import com.algolia.instantsearch.highlighting.Highlightable 4 | import com.algolia.search.model.Attribute 5 | import com.algolia.search.model.ObjectID 6 | import com.algolia.search.model.indexing.Indexable 7 | import kotlinx.serialization.Serializable 8 | import kotlinx.serialization.json.JsonObject 9 | 10 | @Serializable 11 | data class Movie( 12 | val title: String, 13 | override val objectID: ObjectID, 14 | override val _highlightResult: JsonObject? 15 | ) : Indexable, Highlightable { 16 | 17 | val highlightedTitle 18 | get() = getHighlight(Attribute("title")) 19 | } 20 | -------------------------------------------------------------------------------- /examples/android/src/main/kotlin/com/algolia/instantsearch/examples/android/codex/multisearch/README.md: -------------------------------------------------------------------------------- 1 | # Multi-index search implementation example 2 | 3 | Search experience consisting of search in two indices: 4 | - Actors 5 | - Films 6 | 7 | Demonstrates simultaneous search in multiple indices 8 | 9 | ## How to run this example 10 | 11 | ### 1. Clone this repository 12 | 13 | ```sh 14 | git clone git@github.com:algolia/instantsearch-android.git 15 | ``` 16 | 17 | ### 2. Build the project 18 | 19 | ```sh 20 | ./gradlew :examples:android:assembleDebug 21 | ``` 22 | 23 | ### 3. Install the app 24 | 25 | ```sh 26 | ./gradlew :examples:android:installDebug 27 | ``` 28 | 29 | ### 4. Launch the example 30 | 31 | The example is under `Code Exchange > Multiple Index`. 32 | -------------------------------------------------------------------------------- /examples/android/src/main/kotlin/com/algolia/instantsearch/examples/android/codex/suggestions/categories/Suggestion.kt: -------------------------------------------------------------------------------- 1 | package com.algolia.instantsearch.examples.android.codex.suggestions.categories 2 | 3 | import com.algolia.instantsearch.core.highlighting.HighlightedString 4 | import com.algolia.instantsearch.highlighting.Highlightable 5 | import com.algolia.search.model.Attribute 6 | import kotlinx.serialization.Serializable 7 | import kotlinx.serialization.json.JsonObject 8 | 9 | @Serializable 10 | data class Suggestion( 11 | val query: String, 12 | override val _highlightResult: JsonObject? = null 13 | ) : Highlightable { 14 | 15 | val highlightedQuery: HighlightedString? 16 | get() = getHighlight(Attribute("query")) 17 | } 18 | -------------------------------------------------------------------------------- /examples/android/src/main/kotlin/com/algolia/instantsearch/examples/android/codex/suggestions/hits/Product.kt: -------------------------------------------------------------------------------- 1 | package com.algolia.instantsearch.examples.android.codex.suggestions.hits 2 | 3 | import com.algolia.search.model.ObjectID 4 | import com.algolia.search.model.indexing.Indexable 5 | import kotlinx.serialization.Serializable 6 | 7 | @Serializable 8 | data class Product( 9 | val name: String, 10 | val description: String, 11 | val image: String, 12 | override val objectID: ObjectID 13 | ) : Indexable 14 | -------------------------------------------------------------------------------- /examples/android/src/main/kotlin/com/algolia/instantsearch/examples/android/codex/suggestions/hits/Suggestion.kt: -------------------------------------------------------------------------------- 1 | package com.algolia.instantsearch.examples.android.codex.suggestions.hits 2 | 3 | import com.algolia.instantsearch.core.highlighting.HighlightedString 4 | import com.algolia.instantsearch.highlighting.Highlightable 5 | import com.algolia.search.model.Attribute 6 | import kotlinx.serialization.Serializable 7 | import kotlinx.serialization.json.JsonObject 8 | 9 | @Serializable 10 | data class Suggestion( 11 | val query: String, 12 | override val _highlightResult: JsonObject? = null 13 | ) : Highlightable { 14 | 15 | val highlightedQuery: HighlightedString? 16 | get() = getHighlight(Attribute("query")) 17 | } 18 | -------------------------------------------------------------------------------- /examples/android/src/main/kotlin/com/algolia/instantsearch/examples/android/codex/suggestions/query/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.algolia.instantsearch.examples.android.codex.suggestions.query 2 | 3 | import android.os.Bundle 4 | import androidx.activity.ComponentActivity 5 | import androidx.activity.compose.setContent 6 | import androidx.activity.viewModels 7 | import androidx.compose.material.MaterialTheme 8 | 9 | class MainActivity : ComponentActivity() { 10 | 11 | private val viewModel: MainViewModel by viewModels() 12 | 13 | override fun onCreate(savedInstanceState: Bundle?) { 14 | super.onCreate(savedInstanceState) 15 | setContent { 16 | MaterialTheme { 17 | SearchScreen( 18 | searchBoxState = viewModel.searchBoxState, 19 | suggestionsState = viewModel.suggestionsState, 20 | ) 21 | } 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /examples/android/src/main/kotlin/com/algolia/instantsearch/examples/android/codex/suggestions/query/Suggestion.kt: -------------------------------------------------------------------------------- 1 | package com.algolia.instantsearch.examples.android.codex.suggestions.query 2 | 3 | import com.algolia.instantsearch.core.highlighting.HighlightedString 4 | import com.algolia.instantsearch.highlighting.Highlightable 5 | import com.algolia.search.model.Attribute 6 | import kotlinx.serialization.Serializable 7 | import kotlinx.serialization.json.JsonObject 8 | 9 | @Serializable 10 | data class Suggestion( 11 | val query: String, 12 | override val _highlightResult: JsonObject? = null 13 | ) : Highlightable { 14 | 15 | val highlightedQuery: HighlightedString? 16 | get() = getHighlight(Attribute("query")) 17 | } 18 | -------------------------------------------------------------------------------- /examples/android/src/main/kotlin/com/algolia/instantsearch/examples/android/codex/suggestions/recent/Suggestion.kt: -------------------------------------------------------------------------------- 1 | package com.algolia.instantsearch.examples.android.codex.suggestions.recent 2 | 3 | import com.algolia.instantsearch.core.highlighting.HighlightedString 4 | import com.algolia.instantsearch.highlighting.Highlightable 5 | import com.algolia.search.model.Attribute 6 | import kotlinx.serialization.Serializable 7 | import kotlinx.serialization.json.JsonObject 8 | 9 | @Serializable 10 | data class Suggestion( 11 | val query: String, 12 | override val _highlightResult: JsonObject? = null 13 | ) : Highlightable { 14 | 15 | val highlightedQuery: HighlightedString? 16 | get() = getHighlight(Attribute("query")) 17 | } 18 | -------------------------------------------------------------------------------- /examples/android/src/main/kotlin/com/algolia/instantsearch/examples/android/codex/voice/Product.kt: -------------------------------------------------------------------------------- 1 | package com.algolia.instantsearch.examples.android.codex.voice 2 | 3 | import com.algolia.instantsearch.highlighting.Highlightable 4 | import com.algolia.search.model.Attribute 5 | import com.algolia.search.model.ObjectID 6 | import com.algolia.search.model.indexing.Indexable 7 | import kotlinx.serialization.Serializable 8 | import kotlinx.serialization.json.JsonObject 9 | 10 | @Serializable 11 | data class Product( 12 | val name: String, 13 | val description: String, 14 | val image: String, 15 | override val objectID: ObjectID, 16 | override val _highlightResult: JsonObject? 17 | ) : Indexable, Highlightable { 18 | 19 | val highlightedName 20 | get() = getHighlight(Attribute("name")) 21 | 22 | val highlightedDescription 23 | get() = getHighlight(Attribute("description")) 24 | } 25 | -------------------------------------------------------------------------------- /examples/android/src/main/kotlin/com/algolia/instantsearch/examples/android/guides/compose/theme/Color.kt: -------------------------------------------------------------------------------- 1 | package com.algolia.instantsearch.examples.android.guides.compose.theme 2 | 3 | import androidx.compose.ui.graphics.Color 4 | 5 | val Purple200 = Color(0xFFBB86FC) 6 | val Purple500 = Color(0xFF6200EE) 7 | val Purple700 = Color(0xFF3700B3) 8 | val Teal200 = Color(0xFF03DAC5) 9 | -------------------------------------------------------------------------------- /examples/android/src/main/kotlin/com/algolia/instantsearch/examples/android/guides/compose/theme/Shape.kt: -------------------------------------------------------------------------------- 1 | package com.algolia.instantsearch.examples.android.guides.compose.theme 2 | 3 | import androidx.compose.foundation.shape.RoundedCornerShape 4 | import androidx.compose.material.Shapes 5 | import androidx.compose.ui.unit.dp 6 | 7 | val Shapes = Shapes( 8 | small = RoundedCornerShape(4.dp), 9 | medium = RoundedCornerShape(4.dp), 10 | large = RoundedCornerShape(0.dp) 11 | ) 12 | -------------------------------------------------------------------------------- /examples/android/src/main/kotlin/com/algolia/instantsearch/examples/android/guides/compose/theme/Type.kt: -------------------------------------------------------------------------------- 1 | package com.algolia.instantsearch.examples.android.guides.compose.theme 2 | 3 | import androidx.compose.material.Typography 4 | import androidx.compose.ui.text.TextStyle 5 | import androidx.compose.ui.text.font.FontFamily 6 | import androidx.compose.ui.text.font.FontWeight 7 | import androidx.compose.ui.unit.sp 8 | 9 | // Set of Material typography styles to start with 10 | val Typography = Typography( 11 | body1 = TextStyle( 12 | fontFamily = FontFamily.Default, 13 | fontWeight = FontWeight.Normal, 14 | fontSize = 16.sp 15 | ) 16 | ) 17 | -------------------------------------------------------------------------------- /examples/android/src/main/kotlin/com/algolia/instantsearch/examples/android/guides/model/Product.kt: -------------------------------------------------------------------------------- 1 | package com.algolia.instantsearch.examples.android.guides.model 2 | 3 | import com.algolia.instantsearch.core.highlighting.HighlightedString 4 | import com.algolia.instantsearch.highlighting.Highlightable 5 | import com.algolia.search.model.Attribute 6 | import com.algolia.search.model.ObjectID 7 | import com.algolia.search.model.indexing.Indexable 8 | import kotlinx.serialization.Serializable 9 | import kotlinx.serialization.json.JsonObject 10 | 11 | @Serializable 12 | data class Product( 13 | val name: String, 14 | val image: String, 15 | val price: Double, 16 | val description: String, 17 | override val objectID: ObjectID, 18 | override val _highlightResult: JsonObject? 19 | ) : Indexable, Highlightable { 20 | 21 | val highlightedName: HighlightedString? 22 | get() = getHighlight(Attribute("name")) 23 | } 24 | -------------------------------------------------------------------------------- /examples/android/src/main/kotlin/com/algolia/instantsearch/examples/android/guides/model/Suggestion.kt: -------------------------------------------------------------------------------- 1 | package com.algolia.instantsearch.examples.android.guides.model 2 | 3 | import com.algolia.instantsearch.core.highlighting.HighlightedString 4 | import com.algolia.instantsearch.highlighting.Highlightable 5 | import com.algolia.search.model.Attribute 6 | import com.algolia.search.model.ObjectID 7 | import com.algolia.search.model.indexing.Indexable 8 | import kotlinx.serialization.Serializable 9 | import kotlinx.serialization.json.JsonObject 10 | 11 | @Serializable 12 | data class Suggestion( 13 | val query: String, 14 | override val objectID: ObjectID, 15 | override val _highlightResult: JsonObject? 16 | ) : Indexable, Highlightable { 17 | 18 | val highlightedQuery: HighlightedString? 19 | get() = getHighlight(Attribute("query")) 20 | } 21 | -------------------------------------------------------------------------------- /examples/android/src/main/kotlin/com/algolia/instantsearch/examples/android/showcase/androidview/README.md: -------------------------------------------------------------------------------- 1 | # InstantSearch Android Showcase 2 | 3 | A showcase of widgets available in `com.algolia:instantsearch-android`. 4 | 5 | 6 | 7 | ## How to run this example 8 | 9 | ### 1. Clone this repository 10 | 11 | ```sh 12 | git clone git@github.com:algolia/instantsearch-android.git 13 | ``` 14 | 15 | ### 2. Build the project 16 | 17 | ```sh 18 | ./gradlew :examples:android:assembleDebug 19 | ``` 20 | 21 | ### 3. Install the app 22 | 23 | ```sh 24 | ./gradlew :examples:android:installDebug 25 | ``` 26 | 27 | ### 4. Launch the example 28 | 29 | The widgets showcase is under `Showcase > Imperative UI`. 30 | 31 | ## Additional resources 32 | Learn more about InstantSearch Android [widgets](https://www.algolia.com/doc/guides/building-search-ui/widgets/showcase/android/) in the Algolia documentation. 33 | -------------------------------------------------------------------------------- /examples/android/src/main/kotlin/com/algolia/instantsearch/examples/android/showcase/androidview/customdata/Banner.kt: -------------------------------------------------------------------------------- 1 | package com.algolia.instantsearch.examples.android.showcase.androidview.customdata 2 | 3 | import kotlinx.serialization.Serializable 4 | 5 | @Serializable 6 | data class Banner( 7 | val title: String?, 8 | val banner: String?, 9 | val link: String, 10 | val redirect: String? 11 | ) 12 | -------------------------------------------------------------------------------- /examples/android/src/main/kotlin/com/algolia/instantsearch/examples/android/showcase/androidview/filter/list/FilterListViewHolder.kt: -------------------------------------------------------------------------------- 1 | package com.algolia.instantsearch.examples.android.showcase.androidview.filter.list 2 | 3 | import android.view.View 4 | import androidx.recyclerview.widget.RecyclerView 5 | import com.algolia.instantsearch.examples.android.databinding.ListItemSelectableBinding 6 | 7 | class FilterListViewHolder(val binding: ListItemSelectableBinding) : 8 | RecyclerView.ViewHolder(binding.root) { 9 | 10 | fun bind(text: String, selected: Boolean, onClickListener: View.OnClickListener) { 11 | binding.root.setOnClickListener(onClickListener) 12 | binding.selectableItemName.text = text 13 | binding.selectableItemIcon.visibility = if (selected) View.VISIBLE else View.INVISIBLE 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /examples/android/src/main/kotlin/com/algolia/instantsearch/examples/android/showcase/androidview/filter/range/BoundsTextView.kt: -------------------------------------------------------------------------------- 1 | package com.algolia.instantsearch.examples.android.showcase.androidview.filter.range 2 | 3 | import android.widget.TextView 4 | import com.algolia.instantsearch.core.Callback 5 | import com.algolia.instantsearch.core.number.range.NumberRangeView 6 | import com.algolia.instantsearch.core.number.range.Range 7 | 8 | 9 | class BoundsTextView(val view: TextView) : NumberRangeView { 10 | 11 | override var onRangeChanged: Callback>? = null 12 | 13 | private var bounds: Range? = null 14 | 15 | override fun setBounds(bounds: Range?) { 16 | this.bounds = bounds 17 | view.text = bounds?.let { 18 | "Bounds: ${it.min} to ${it.max}" 19 | } ?: "No bounds" 20 | } 21 | 22 | override fun setRange(range: Range?) = Unit 23 | } 24 | -------------------------------------------------------------------------------- /examples/android/src/main/kotlin/com/algolia/instantsearch/examples/android/showcase/androidview/filter/rating/RatingTextView.kt: -------------------------------------------------------------------------------- 1 | package com.algolia.instantsearch.examples.android.showcase.androidview.filter.rating 2 | 3 | import android.widget.TextView 4 | import com.algolia.instantsearch.core.Callback 5 | import com.algolia.instantsearch.core.number.range.NumberRangeView 6 | import com.algolia.instantsearch.core.number.range.Range 7 | 8 | class RatingTextView(private val textView: TextView) : NumberRangeView { 9 | 10 | override var onRangeChanged: Callback>? = null 11 | 12 | override fun setBounds(bounds: Range?) = Unit 13 | 14 | override fun setRange(range: Range?) { 15 | textView.text = "${range?.min ?: 0}" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /examples/android/src/main/kotlin/com/algolia/instantsearch/examples/android/showcase/androidview/list/actor/Actor.kt: -------------------------------------------------------------------------------- 1 | package com.algolia.instantsearch.examples.android.showcase.androidview.list.actor 2 | 3 | import com.algolia.search.model.ObjectID 4 | import com.algolia.search.model.indexing.Indexable 5 | import kotlinx.serialization.Serializable 6 | 7 | @Serializable 8 | data class Actor( 9 | val name: String, 10 | override val objectID: ObjectID 11 | ) : Indexable 12 | -------------------------------------------------------------------------------- /examples/android/src/main/kotlin/com/algolia/instantsearch/examples/android/showcase/androidview/list/actor/ActorViewHolder.kt: -------------------------------------------------------------------------------- 1 | package com.algolia.instantsearch.examples.android.showcase.androidview.list.actor 2 | 3 | import androidx.recyclerview.widget.RecyclerView 4 | import com.algolia.instantsearch.examples.android.databinding.ListItemActorBinding 5 | 6 | class ActorViewHolder(private val binding: ListItemActorBinding) : 7 | RecyclerView.ViewHolder(binding.root) { 8 | 9 | fun bind(actor: Actor) { 10 | binding.actorName.text = actor.name 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /examples/android/src/main/kotlin/com/algolia/instantsearch/examples/android/showcase/androidview/list/actor/ActorViewHolderSmall.kt: -------------------------------------------------------------------------------- 1 | package com.algolia.instantsearch.examples.android.showcase.androidview.list.actor 2 | 3 | import androidx.recyclerview.widget.RecyclerView 4 | import com.algolia.instantsearch.examples.android.databinding.ListItemSmallBinding 5 | 6 | class ActorViewHolderSmall(val binding: ListItemSmallBinding) : 7 | RecyclerView.ViewHolder(binding.root) { 8 | 9 | fun bind(actor: Actor) { 10 | binding.itemName.text = actor.name 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /examples/android/src/main/kotlin/com/algolia/instantsearch/examples/android/showcase/androidview/list/header/HeaderViewHolder.kt: -------------------------------------------------------------------------------- 1 | package com.algolia.instantsearch.examples.android.showcase.androidview.list.header 2 | 3 | import android.widget.TextView 4 | import androidx.recyclerview.widget.RecyclerView 5 | 6 | class HeaderViewHolder(val view: TextView) : RecyclerView.ViewHolder(view) { 7 | 8 | fun bind(string: String) { 9 | view.text = string 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /examples/android/src/main/kotlin/com/algolia/instantsearch/examples/android/showcase/androidview/list/movie/MovieDiffUtil.kt: -------------------------------------------------------------------------------- 1 | package com.algolia.instantsearch.examples.android.showcase.androidview.list.movie 2 | 3 | import androidx.recyclerview.widget.DiffUtil 4 | 5 | object MovieDiffUtil : DiffUtil.ItemCallback() { 6 | 7 | override fun areItemsTheSame( 8 | oldItem: Movie, 9 | newItem: Movie 10 | ): Boolean { 11 | return oldItem.objectID == newItem.objectID 12 | } 13 | 14 | override fun areContentsTheSame( 15 | oldItem: Movie, 16 | newItem: Movie 17 | ): Boolean { 18 | return oldItem == newItem 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /examples/android/src/main/kotlin/com/algolia/instantsearch/examples/android/showcase/androidview/list/movie/MovieViewHolderNested.kt: -------------------------------------------------------------------------------- 1 | package com.algolia.instantsearch.examples.android.showcase.androidview.list.movie 2 | 3 | import androidx.recyclerview.widget.RecyclerView 4 | import coil.load 5 | import com.algolia.instantsearch.examples.android.databinding.ListItemMovieBinding 6 | 7 | class MovieViewHolderNested(private val binding: ListItemMovieBinding) : 8 | RecyclerView.ViewHolder(binding.root) { 9 | 10 | fun bind(movie: Movie) { 11 | binding.itemTitle.text = movie.title 12 | binding.itemSubtitle.text = movie.genre.sorted().joinToString { it } 13 | binding.itemCaption.text = movie.year 14 | binding.itemImage.load(movie.image) { 15 | placeholder(android.R.drawable.ic_media_play) 16 | error(android.R.drawable.ic_media_play) 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /examples/android/src/main/kotlin/com/algolia/instantsearch/examples/android/showcase/androidview/list/paging/PagingMultipleIndexItem.kt: -------------------------------------------------------------------------------- 1 | package com.algolia.instantsearch.examples.android.showcase.androidview.list.paging 2 | 3 | import com.algolia.instantsearch.examples.android.showcase.androidview.list.actor.ActorAdapterNested 4 | import com.algolia.instantsearch.examples.android.showcase.androidview.list.movie.MovieAdapterNested 5 | 6 | 7 | sealed class PagingMultipleIndexItem { 8 | 9 | data class Header(val name: String): PagingMultipleIndexItem() 10 | 11 | data class Movies(val adapter: MovieAdapterNested) : PagingMultipleIndexItem() 12 | 13 | data class Actors(val adapter: ActorAdapterNested) : PagingMultipleIndexItem() 14 | } 15 | -------------------------------------------------------------------------------- /examples/android/src/main/kotlin/com/algolia/instantsearch/examples/android/showcase/androidview/list/product/Product.kt: -------------------------------------------------------------------------------- 1 | package com.algolia.instantsearch.examples.android.showcase.androidview.list.product 2 | 3 | import com.algolia.search.model.ObjectID 4 | import com.algolia.search.model.indexing.Indexable 5 | import kotlinx.serialization.SerialName 6 | import kotlinx.serialization.Serializable 7 | 8 | @Serializable 9 | data class Product( 10 | val name: String, 11 | val description: String, 12 | val brand: String? = null, 13 | val categories: List, 14 | val type: String, 15 | val price: Double, 16 | @SerialName("price_range") val priceRange: String, 17 | val image: String, 18 | val url: String, 19 | @SerialName("free_shipping") val freeShipping: Boolean, 20 | val rating: Int = 0, 21 | val popularity: Long, 22 | override val objectID: ObjectID 23 | ) : Indexable 24 | -------------------------------------------------------------------------------- /examples/android/src/main/kotlin/com/algolia/instantsearch/examples/android/showcase/androidview/list/suggestion/Suggestion.kt: -------------------------------------------------------------------------------- 1 | package com.algolia.instantsearch.examples.android.showcase.androidview.list.suggestion 2 | 3 | import com.algolia.instantsearch.core.highlighting.HighlightedString 4 | import com.algolia.instantsearch.highlighting.Highlightable 5 | import com.algolia.search.model.Attribute 6 | import com.algolia.search.model.ObjectID 7 | import com.algolia.search.model.indexing.Indexable 8 | import kotlinx.serialization.Serializable 9 | import kotlinx.serialization.json.JsonObject 10 | 11 | @Serializable 12 | data class Suggestion( 13 | val query: String, 14 | override val objectID: ObjectID, 15 | override val _highlightResult: JsonObject? 16 | ) : Indexable, Highlightable { 17 | 18 | val highlightedQuery: HighlightedString? 19 | get() = getHighlight(Attribute("query")) 20 | } 21 | -------------------------------------------------------------------------------- /examples/android/src/main/kotlin/com/algolia/instantsearch/examples/android/showcase/compose/model/Actor.kt: -------------------------------------------------------------------------------- 1 | package com.algolia.instantsearch.examples.android.showcase.compose.model 2 | 3 | import com.algolia.search.model.ObjectID 4 | import com.algolia.search.model.indexing.Indexable 5 | import kotlinx.serialization.Serializable 6 | 7 | @Serializable 8 | data class Actor( 9 | val name: String, 10 | override val objectID: ObjectID 11 | ) : Indexable 12 | -------------------------------------------------------------------------------- /examples/android/src/main/kotlin/com/algolia/instantsearch/examples/android/showcase/compose/model/Banner.kt: -------------------------------------------------------------------------------- 1 | package com.algolia.instantsearch.examples.android.showcase.compose.model 2 | 3 | import kotlinx.serialization.Serializable 4 | 5 | @Serializable 6 | data class Banner( 7 | val title: String?, 8 | val banner: String?, 9 | val link: String 10 | ) 11 | -------------------------------------------------------------------------------- /examples/android/src/main/kotlin/com/algolia/instantsearch/examples/android/showcase/compose/model/Product.kt: -------------------------------------------------------------------------------- 1 | package com.algolia.instantsearch.examples.android.showcase.compose.model 2 | 3 | import com.algolia.search.model.ObjectID 4 | import com.algolia.search.model.indexing.Indexable 5 | import kotlinx.serialization.SerialName 6 | import kotlinx.serialization.Serializable 7 | 8 | @Serializable 9 | data class Product( 10 | val name: String, 11 | val description: String, 12 | val brand: String? = null, 13 | val categories: List, 14 | val type: String, 15 | val price: Double, 16 | @SerialName("price_range") val priceRange: String, 17 | val image: String, 18 | val url: String, 19 | @SerialName("free_shipping") val freeShipping: Boolean, 20 | val rating: Int = 0, 21 | val popularity: Long, 22 | override val objectID: ObjectID 23 | ) : Indexable 24 | -------------------------------------------------------------------------------- /examples/android/src/main/kotlin/com/algolia/instantsearch/examples/android/showcase/compose/ui/Shape.kt: -------------------------------------------------------------------------------- 1 | package com.algolia.instantsearch.examples.android.showcase.compose.ui 2 | 3 | import androidx.compose.foundation.shape.RoundedCornerShape 4 | import androidx.compose.material.Shapes 5 | import androidx.compose.ui.unit.dp 6 | 7 | val Shapes = Shapes( 8 | small = RoundedCornerShape(4.dp), 9 | medium = RoundedCornerShape(4.dp), 10 | large = RoundedCornerShape(0.dp) 11 | ) 12 | -------------------------------------------------------------------------------- /examples/android/src/main/kotlin/com/algolia/instantsearch/examples/android/showcase/compose/ui/Theme.kt: -------------------------------------------------------------------------------- 1 | package com.algolia.instantsearch.examples.android.showcase.compose.ui 2 | 3 | import androidx.compose.material.MaterialTheme 4 | import androidx.compose.material.lightColors 5 | import androidx.compose.runtime.Composable 6 | 7 | private val LightColorPalette = lightColors( 8 | primary = BlueDark, 9 | onPrimary = White, 10 | secondary = White, 11 | onSecondary = GreyDark, 12 | onSurface = BlackLight, 13 | background = WhiteLight, 14 | onBackground = BlackLight, 15 | 16 | ) 17 | 18 | @Composable 19 | fun ShowcaseTheme(content: @Composable() () -> Unit) { 20 | MaterialTheme( 21 | colors = LightColorPalette, 22 | typography = Typography, 23 | shapes = Shapes, 24 | content = content 25 | ) 26 | } 27 | -------------------------------------------------------------------------------- /examples/android/src/main/kotlin/com/algolia/instantsearch/examples/android/showcase/compose/ui/component/RestoreFab.kt: -------------------------------------------------------------------------------- 1 | package com.algolia.instantsearch.examples.android.showcase.compose.ui.component 2 | 3 | import androidx.compose.material.FloatingActionButton 4 | import androidx.compose.material.Icon 5 | import androidx.compose.material.MaterialTheme 6 | import androidx.compose.material.icons.Icons 7 | import androidx.compose.material.icons.filled.Restore 8 | import androidx.compose.runtime.Composable 9 | 10 | @Composable 11 | fun RestoreFab(onClick: () -> Unit = {}) { 12 | FloatingActionButton( 13 | backgroundColor = MaterialTheme.colors.background, 14 | onClick = onClick 15 | ) { 16 | Icon( 17 | imageVector = Icons.Default.Restore, 18 | contentDescription = "restore" 19 | ) 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /examples/android/src/main/res/drawable-anydpi/ic_filter_list.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /examples/android/src/main/res/drawable/ic_add.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /examples/android/src/main/res/drawable/ic_add_shopping_cart.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /examples/android/src/main/res/drawable/ic_arrow_down.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /examples/android/src/main/res/drawable/ic_arrow_up.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /examples/android/src/main/res/drawable/ic_arrow_up_right.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /examples/android/src/main/res/drawable/ic_check.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /examples/android/src/main/res/drawable/ic_close_hint.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 12 | 13 | -------------------------------------------------------------------------------- /examples/android/src/main/res/drawable/ic_delete.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /examples/android/src/main/res/drawable/ic_info.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /examples/android/src/main/res/drawable/ic_microphone_outline.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | -------------------------------------------------------------------------------- /examples/android/src/main/res/drawable/ic_remove.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /examples/android/src/main/res/drawable/ic_restore.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /examples/android/src/main/res/drawable/ic_search_hint.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 11 | 12 | -------------------------------------------------------------------------------- /examples/android/src/main/res/drawable/query_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /examples/android/src/main/res/drawable/rectangle.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 9 | 12 | 13 | -------------------------------------------------------------------------------- /examples/android/src/main/res/drawable/thumb.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /examples/android/src/main/res/layout/activity_getting_started.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | -------------------------------------------------------------------------------- /examples/android/src/main/res/layout/autocompletetextfield.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /examples/android/src/main/res/layout/filter_chip.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /examples/android/src/main/res/layout/fragment_items.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | -------------------------------------------------------------------------------- /examples/android/src/main/res/layout/header_item.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /examples/android/src/main/res/layout/list_item_actor.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 19 | 20 | -------------------------------------------------------------------------------- /examples/android/src/main/res/layout/list_item_header.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /examples/android/src/main/res/layout/menu_item.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /examples/android/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /examples/android/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algolia/instantsearch-android/eaf37a61303a8b9c5688a596e8aeab29dfbba398/examples/android/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /examples/android/src/main/res/mipmap-hdpi/ic_launcher_adaptive_back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algolia/instantsearch-android/eaf37a61303a8b9c5688a596e8aeab29dfbba398/examples/android/src/main/res/mipmap-hdpi/ic_launcher_adaptive_back.png -------------------------------------------------------------------------------- /examples/android/src/main/res/mipmap-hdpi/ic_launcher_adaptive_fore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algolia/instantsearch-android/eaf37a61303a8b9c5688a596e8aeab29dfbba398/examples/android/src/main/res/mipmap-hdpi/ic_launcher_adaptive_fore.png -------------------------------------------------------------------------------- /examples/android/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algolia/instantsearch-android/eaf37a61303a8b9c5688a596e8aeab29dfbba398/examples/android/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /examples/android/src/main/res/mipmap-mdpi/ic_launcher_adaptive_back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algolia/instantsearch-android/eaf37a61303a8b9c5688a596e8aeab29dfbba398/examples/android/src/main/res/mipmap-mdpi/ic_launcher_adaptive_back.png -------------------------------------------------------------------------------- /examples/android/src/main/res/mipmap-mdpi/ic_launcher_adaptive_fore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algolia/instantsearch-android/eaf37a61303a8b9c5688a596e8aeab29dfbba398/examples/android/src/main/res/mipmap-mdpi/ic_launcher_adaptive_fore.png -------------------------------------------------------------------------------- /examples/android/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algolia/instantsearch-android/eaf37a61303a8b9c5688a596e8aeab29dfbba398/examples/android/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /examples/android/src/main/res/mipmap-xhdpi/ic_launcher_adaptive_back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algolia/instantsearch-android/eaf37a61303a8b9c5688a596e8aeab29dfbba398/examples/android/src/main/res/mipmap-xhdpi/ic_launcher_adaptive_back.png -------------------------------------------------------------------------------- /examples/android/src/main/res/mipmap-xhdpi/ic_launcher_adaptive_fore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algolia/instantsearch-android/eaf37a61303a8b9c5688a596e8aeab29dfbba398/examples/android/src/main/res/mipmap-xhdpi/ic_launcher_adaptive_fore.png -------------------------------------------------------------------------------- /examples/android/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algolia/instantsearch-android/eaf37a61303a8b9c5688a596e8aeab29dfbba398/examples/android/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /examples/android/src/main/res/mipmap-xxhdpi/ic_launcher_adaptive_back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algolia/instantsearch-android/eaf37a61303a8b9c5688a596e8aeab29dfbba398/examples/android/src/main/res/mipmap-xxhdpi/ic_launcher_adaptive_back.png -------------------------------------------------------------------------------- /examples/android/src/main/res/mipmap-xxhdpi/ic_launcher_adaptive_fore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algolia/instantsearch-android/eaf37a61303a8b9c5688a596e8aeab29dfbba398/examples/android/src/main/res/mipmap-xxhdpi/ic_launcher_adaptive_fore.png -------------------------------------------------------------------------------- /examples/android/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algolia/instantsearch-android/eaf37a61303a8b9c5688a596e8aeab29dfbba398/examples/android/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /examples/android/src/main/res/mipmap-xxxhdpi/ic_launcher_adaptive_back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algolia/instantsearch-android/eaf37a61303a8b9c5688a596e8aeab29dfbba398/examples/android/src/main/res/mipmap-xxxhdpi/ic_launcher_adaptive_back.png -------------------------------------------------------------------------------- /examples/android/src/main/res/mipmap-xxxhdpi/ic_launcher_adaptive_fore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algolia/instantsearch-android/eaf37a61303a8b9c5688a596e8aeab29dfbba398/examples/android/src/main/res/mipmap-xxxhdpi/ic_launcher_adaptive_fore.png -------------------------------------------------------------------------------- /examples/androidtv/README.md: -------------------------------------------------------------------------------- 1 | # InstantSearch examples for Android TV 2 | 3 | ![InstantSearch Examples for Android TV](/docs/img/examples/androidtv.png) 4 | 5 | ## How to run this example 6 | 7 | ### 1. Clone this repository 8 | 9 | ```sh 10 | git clone git@github.com:algolia/instantsearch-android.git 11 | ``` 12 | 13 | ### 2. Build the project 14 | 15 | ```sh 16 | ./gradlew :examples:androidtv:assembleDebug 17 | ``` 18 | 19 | ### 3. Install the app 20 | 21 | ```sh 22 | ./gradlew :examples:androidtv:installDebug 23 | ``` 24 | -------------------------------------------------------------------------------- /examples/androidtv/src/main/java/com/algolia/instantsearch/examples/androidtv/Suggestion.kt: -------------------------------------------------------------------------------- 1 | package com.algolia.instantsearch.examples.androidtv 2 | 3 | import com.algolia.instantsearch.core.highlighting.HighlightedString 4 | import com.algolia.instantsearch.highlighting.Highlightable 5 | import com.algolia.search.model.Attribute 6 | import kotlinx.serialization.Serializable 7 | import kotlinx.serialization.json.JsonObject 8 | 9 | @Serializable 10 | data class Suggestion( 11 | val query: String, 12 | override val _highlightResult: JsonObject? = null 13 | ) : Highlightable { 14 | 15 | val highlightedQuery: HighlightedString? 16 | get() = getHighlight(Attribute("query")) 17 | } 18 | -------------------------------------------------------------------------------- /examples/androidtv/src/main/java/com/algolia/instantsearch/examples/androidtv/ui/Color.kt: -------------------------------------------------------------------------------- 1 | package com.algolia.instantsearch.examples.androidtv.ui 2 | 3 | import androidx.compose.ui.graphics.Color 4 | 5 | val blue200 = Color(0xFF3377FF) 6 | val blue = Color(0xFF2266EE) 7 | val teal200 = Color(0XFF68E4DC) 8 | val errorColor = Color(0xFFB00020) 9 | val golden = Color(0xFFF2A23C) 10 | val grey = Color(0xFF989B9E) 11 | val searchBackground = Color(0xFF3D3D3D) 12 | val white = Color(0xFFDDDDDD) 13 | -------------------------------------------------------------------------------- /examples/androidtv/src/main/java/com/algolia/instantsearch/examples/androidtv/ui/Theme.kt: -------------------------------------------------------------------------------- 1 | package com.algolia.instantsearch.examples.androidtv.ui 2 | 3 | import androidx.compose.material.MaterialTheme 4 | import androidx.compose.material.darkColors 5 | import androidx.compose.runtime.Composable 6 | import androidx.compose.ui.graphics.Color.Companion.Black 7 | import androidx.compose.ui.graphics.Color.Companion.White 8 | 9 | @Composable 10 | fun AppTheme(content: @Composable() () -> Unit) { 11 | MaterialTheme( 12 | colors = ColorPalette, 13 | content = content 14 | ) 15 | } 16 | 17 | private val ColorPalette = darkColors( 18 | primary = blue200, 19 | primaryVariant = blue, 20 | secondary = teal200, 21 | background = Black, 22 | surface = Black, 23 | onPrimary = Black, 24 | onSecondary = White, 25 | onBackground = White, 26 | onSurface = White, 27 | error = errorColor 28 | ) 29 | -------------------------------------------------------------------------------- /examples/androidtv/src/main/res/drawable/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algolia/instantsearch-android/eaf37a61303a8b9c5688a596e8aeab29dfbba398/examples/androidtv/src/main/res/drawable/ic_launcher.png -------------------------------------------------------------------------------- /examples/androidtv/src/main/res/drawable/movie.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algolia/instantsearch-android/eaf37a61303a8b9c5688a596e8aeab29dfbba398/examples/androidtv/src/main/res/drawable/movie.png -------------------------------------------------------------------------------- /examples/androidtv/src/main/res/layout/activity_details.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /examples/androidtv/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /examples/androidtv/src/main/res/mipmap-hdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algolia/instantsearch-android/eaf37a61303a8b9c5688a596e8aeab29dfbba398/examples/androidtv/src/main/res/mipmap-hdpi/ic_launcher.webp -------------------------------------------------------------------------------- /examples/androidtv/src/main/res/mipmap-mdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algolia/instantsearch-android/eaf37a61303a8b9c5688a596e8aeab29dfbba398/examples/androidtv/src/main/res/mipmap-mdpi/ic_launcher.webp -------------------------------------------------------------------------------- /examples/androidtv/src/main/res/mipmap-xhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algolia/instantsearch-android/eaf37a61303a8b9c5688a596e8aeab29dfbba398/examples/androidtv/src/main/res/mipmap-xhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /examples/androidtv/src/main/res/mipmap-xxhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algolia/instantsearch-android/eaf37a61303a8b9c5688a596e8aeab29dfbba398/examples/androidtv/src/main/res/mipmap-xxhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /examples/androidtv/src/main/res/mipmap-xxxhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algolia/instantsearch-android/eaf37a61303a8b9c5688a596e8aeab29dfbba398/examples/androidtv/src/main/res/mipmap-xxxhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /examples/androidtv/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | AndroidTV Showcase 3 | 4 | -------------------------------------------------------------------------------- /examples/androidtv/src/main/res/values/themes.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 |